引言
在單一項目中,特別是模塊化的開發(fā)模式下,我們通常會抽出一些全局共用的邏輯,放在一個 base-xxx 之類的模塊里,在其他模塊中,通過
implementation project(path: ':base-xxx')的方式進行模塊依賴。
但開頭也有提到,這種形式多用于單項目內部。如果需要跨項目使用同一個模塊,就不太合適了。雖然借助svn、git等版本控制工具也可以同步代碼,但需要對文件夾單獨進行版本管理,即外部文件夾屬于一個git項目,內部文件夾屬于另一個git項目,這種復雜的目錄關系和文件管理會造成很強的歧義,而且引入了很多不必要的管理工作。
對于這種公用模塊,更好的管理辦法是將其當作一個單獨的項目來維護。使用方就不再關心起具體的實現,只需要對其輸出物進行依賴即可。
簡單來看的話,可以把輸出的aar或jar包直接拿來用,但使用aar包有一個顯著的缺陷:依賴傳遞丟失。
gradle腳本的依賴項里,使用 implementation 和 api 聲明的依賴作用域不同,其中 api 可以對外暴露自身依賴,使用方也同步獲得對應依賴。但打包成aar或jar后,這部分信息就丟失了。
而在Maven機制中,對依賴的管理是依靠pom文件實現的,dependencies中添加的依賴項會同時下載對應的包和pom文件,本文我們就一起來看看怎么通過gradle腳本上傳自己的庫,完成gradle依賴的支持。
參考文檔:https://docs.gradle.org/current/userguide/publishing_setup.html
上傳者舉例
gradle工具對maven的支持可以說很完善了,在模塊的gradle腳本文件中引用與簡單配置即可。下面貼出完整的子項目腳本,以及對應說明:
apply plugin: 'com.android.library'
apply plugin: 'maven'
android {
compileSdkVersion 30
defaultConfig {
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
api 'com.squareup.okhttp3:okhttp:4.7.2'
api 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.7.2'
}
// ------------- 以下為上傳相關配置 -------------
task androidSourcesJar(type: Jar) {
archiveClassifier.set('sources')
from android.sourceSets.main.java.sourceFiles
}
artifacts {
archives androidSourcesJar
}
mavenDeploy {
repositories {
mavenDeployer {
repository(url: https://nexus.simple.net/repository/android-releases/) {
authentication(userName: xxxxxx, password: xxxxxx)
}
pom.project {
groupId com.simple
artifactId base-xxx
version 1.3.25
packaging 'aar'
}
}
}
}
關鍵部分說明:
apply plugin: 'maven' 引入maven腳本支持,可以使用其中的方法和能力
mavenDeploy 定義一個閉包,名字隨意,這個就是我們要直接執(zhí)行的命令
repository 指定maven倉庫地址和對應用戶信息;可以是mavenCentral,可以是自建的nexus,也可以是本地文件夾路徑uri。
groupId 所屬組,推薦直接使用包名
artifactId 名稱,不解釋
version 發(fā)布的版本,注意與android.defaultConfig中的versionCode、versionName區(qū)分,與這兩者完全無關,maven中只認這個版本名。
artifacts (非必要)用于聲明組件,其中指定對應task:androidSourcesJar,會在打包時執(zhí)行,將 源碼 也打包發(fā)布。
aar和jar包中的是編譯過后的class文件,注釋信息都丟失了,很多變量名和參數名也會變成var1、var2這種,如果是內部使用,建議同時打包源碼,方便開發(fā)人員閱讀與調試。
本地模擬倉庫環(huán)境
在私庫環(huán)境不具備時,可以使用本地文件夾暫時代替,用于驗證編譯過程。對maven來說,只需要指定一個url,能往其中寫入文件與下載對應文件即可,我們將一個本地路徑轉成uri即可使用:
apply plugin: 'com.android.library'
apply plugin: 'maven'
android {
......
}
dependencies {
......
}
mavenDeploy {
repositories {
mavenDeployer {
repository(url: uri("/Users/wwf/Desktop/env/localRepo"))
pom.project {
groupId com.simple
artifactId base-xxx
version 1.3.25
}
}
}
}
拋開源碼,簡化過后就可以得到上面的腳本了,其實 **** 也可以不配置,會根據項目名和模塊名生成對應的 groupId 和 artifactId,版本號為unspecified,但還是建議明確聲明。
執(zhí)行gradle命令:gradle mavenDeploy,注意執(zhí)行目錄。
成功后即可在對應文件夾中發(fā)現如下文件:

使用者舉例
與我們日常開發(fā)相同,需要在項目根腳本中指定要查找依賴的目標倉庫。以mavenCentral為例:
---------- build.gradle in root projec ----------
buildscript {
repositories {
// 等效于mavenCentral()
maven { url "https://repo1.maven.org/maven2/" }
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
......
......
}
}
allprojects {
repositories {
// 等效于mavenCentral()
maven { url "https://repo1.maven.org/maven2/" }
}
}
其中 allprojects 下的 repositories 中聲明的是子項目查找的倉庫。如果書接上文,使用本地倉庫,就需要配置一個本地路徑url,使用maven儲存協(xié)議:
buildscript {
......
}
allprojects {
repositories {
// 等效于mavenCentral()
maven { url "https://repo1.maven.org/maven2/" }
maven { url: uri("/Users/wwf/Desktop/env/localRepo") }
}
}
配置好后就可以像使用遠程倉庫中其他依賴一樣,使用本地倉庫中的包啦!
全文完,如有不足請多指教,共同進步。