最近在做基礎(chǔ)功能和架構(gòu)搭建,所以會(huì)將基礎(chǔ)功能進(jìn)行封裝,并提供一份遠(yuǎn)程依賴.在使用過(guò)程中踩了很多坑.特地進(jìn)行記錄
不想看分析和流程的可以直接點(diǎn)擊查看,重點(diǎn)關(guān)注工程的三個(gè)gradle文件和相關(guān)注釋,MainActivity有引用庫(kù)的類示例示例代碼
在Android中使用第三方的庫(kù)和自己的庫(kù),無(wú)論是遠(yuǎn)程依賴還是本地依賴,通常會(huì)選擇JAR和AAR的形式.而AAR相比JAR包可以包含資源文件.可以有AndroidManifest文件.所以都會(huì)建議使用AAR包的形式進(jìn)行打包.
網(wǎng)上很多示例都只是封裝了自己的代碼,而涉及到第三方的SDK引用,就避而不談,或者是使用jar包的形式.但是使用jar包會(huì)有非常多的問(wèn)題,例如第三方SDK包含了SO庫(kù)(如高德地圖,極光推送),而且由于是基礎(chǔ)封裝的庫(kù),所以必須包含所有的so庫(kù)版本.就會(huì)導(dǎo)致aar包的非常龐大,這時(shí)就需要使用遠(yuǎn)程依賴和動(dòng)態(tài)設(shè)置so支持版本來(lái)解決這個(gè)問(wèn)題.而使用了遠(yuǎn)程依賴,又要解決依賴傳遞的問(wèn)題.
默認(rèn)的AAR包只有代碼,沒(méi)有注釋和源碼.
需要解決的問(wèn)題
- 1.aar包遠(yuǎn)程依賴第三方庫(kù)
- 2.aar包依賴沖突
- 3.aar添加源碼和代碼注釋
解決問(wèn)題前需要了解的兩個(gè)知識(shí)點(diǎn)
從這張圖中可以看到,從Android gradle plugin 3.0.0版本開(kāi)始,推薦使用implementation和api替換到以前使用的compile依賴方法.
上面這張圖是在gradle官網(wǎng)關(guān)于gradle處理依賴的截圖.這里做個(gè)簡(jiǎn)單的整理
參數(shù) | 值 | 意義 |
---|---|---|
force | true | 發(fā)生沖突時(shí)強(qiáng)制使用該依賴,false不強(qiáng)制使用,默認(rèn)為false |
exclude | module : 'lib' | 去掉名為lib的module依賴 |
exclude | group:'org.xx' | 去掉包名為org.xx依賴 |
transitive | false | 不傳遞依賴,true為傳遞,默認(rèn)為false |
在使用過(guò)程中還是發(fā)現(xiàn)有一個(gè)問(wèn)題依舊不能解決.如果對(duì)aar包進(jìn)行了混淆,自己編寫的代碼都被去除了,不知道是什么原因,希望有高人相助.
新建Module并打包AAR流程
1.添加一個(gè)AndroidLibrary模塊
右鍵工程父目錄 -> NEW -> Module -> Android Library
2.修改Library模塊的build.gradle
//在最上方加上maven依賴的插件
...
apply plugin: 'maven'
...//這里忽略了gradle文件原有的配置
//在gradle文件最下方新建一個(gè)打包任務(wù).
//maven上傳,示例代碼將aar輸出到了本地,如果公司有maven私服,可以將地址改為maven私服的地址
def MAVEN_LOCAL_PATH = 'file://localhost/' + rootProject.buildDir
//版本號(hào)
def VERSION = '0.0.1'
//公司名稱
def GROUP_ID = 'com.cicinnus.aartest'
//aar包名稱
def ARTIFACT_ID = 'aartest'
//Maven私服賬號(hào)
//def ACCOUNT = 'xxx'
//Maven私服密碼
//def PWD = 'xxx'
uploadArchives {
repositories {
mavenDeployer {
repository(url: MAVEN_LOCAL_PATH) {
//如果使用的是maven私服,一般都需要賬號(hào)密碼
//authentication(userName :ACCOUNT,password:PWD)
}
pom.groupId = GROUP_ID
pom.artifactId = ARTIFACT_ID
pom.version = VERSION
pom.packaging = 'aar'
}
}
}
3.構(gòu)建aar,輸出到本地
在項(xiàng)目目錄,執(zhí)行命令行./gradlew uploadArchives
或者在AS右邊的gradle插件中
選擇library模塊 -> upload -> 雙擊uploadArchives .等待編譯結(jié)束
編譯結(jié)束后在Library模塊 -> outputs -> aar .就可以找到編譯好的aar包
4.引用本地aar(因?yàn)槿笔?duì)maven的依賴管理,所以本地引用會(huì)導(dǎo)致依賴無(wú)法正確傳遞,意思就是使用本地aar包的方式會(huì)導(dǎo)致遠(yuǎn)程依賴失效.解決方案請(qǐng)繼續(xù)往下)
在app模塊的gradle文件添加
...
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
...
api(name: 'aarlibrary-release', ext: 'aar')
}
5.使用遠(yuǎn)程依賴aar,推薦的解決方案
使用遠(yuǎn)程依賴的方式:
1.maven構(gòu)建的地址填寫maven私服地址
def MAVEN_LOCAL_PATH = 'maven私服地址'
uploadArchives {
repositories {
mavenDeployer {
repository(url: MAVEN_LOCAL_PATH) {
}
...省略部分代碼
}
}
}
2.在工程父目錄的gradle文件添加maven倉(cāng)庫(kù)地址
allprojects {
repositories {
maven {
url 'maven私服地址,與上傳的地址一致'
}
google()
jcenter()
}
}
3.app模塊的gradle使用遠(yuǎn)程依賴,并傳遞依賴,注意最后的transitive
api group: 'com.cicinnus.aartest', name: 'aartest', version: '0.0.1', transitive: true
6.為構(gòu)建的aar添加文檔和源碼包(可選).方便調(diào)用者查看注釋和源碼實(shí)現(xiàn)
在library的module中添加gradle task,以下代碼無(wú)需修改照抄即可,如果只需要文檔可以刪掉archives androidSourcesJar這一行代碼.
在生成aar的同時(shí),在build目錄會(huì)有一個(gè)libs目錄,里面放著源碼和文檔的jar包,如果上傳到maven私服,會(huì)自動(dòng)同時(shí)提交.如果使用本地aar,需要單獨(dú)引入.
//生成文檔注釋
task androidJavadocs(type: Javadoc) {
failOnError = false
source = android.sourceSets.main.java.srcDirs
ext.androidJar = "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar"
classpath += files(ext.androidJar)
}
//將文檔打包成jar
task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
classifier = 'javadoc'
from androidJavadocs.destinationDir
}
//將源碼打包
task androidSourcesJar(type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
//包含文檔和源碼的aar
artifacts {
archives androidSourcesJar
archives androidJavadocsJar
}
總結(jié)最佳方案
使用遠(yuǎn)程aar,最大優(yōu)勢(shì):
- .方便處理依賴沖突,依賴傳遞
不建議使用本地aar的兩個(gè)原因:
- 1.aar中的第三個(gè)庫(kù)無(wú)法使用遠(yuǎn)程依賴
- 2.如果使用本地maven,需要每個(gè)參與開(kāi)發(fā)的人員都配置一個(gè)本地的maven倉(cāng)庫(kù),不現(xiàn)實(shí)
aar最佳使用流程和推薦用法
- 1.配置gradle task,上傳aar包到maven倉(cāng)庫(kù)
- 2.配置遠(yuǎn)程依賴,將依賴的版本號(hào)設(shè)為'+'.意為動(dòng)態(tài)使用最新版本,可以解決aar更新后無(wú)法及時(shí)知道的問(wèn)題
implementation group: 'com.cicinnus.aartest', name: 'aartest', version: '+',transitive:true
- 3.有A,B,C三個(gè)模塊,A為app主模塊,A依賴B和C,B依賴C的部分功能.這時(shí)候可以考慮將B的依賴關(guān)鍵字使用compileOnly,就可以解決最終的依賴沖突問(wèn)題.卻又能在編譯期正常使用C模塊的功能.
compileOnly group: 'com.cicinnus.aartest', name: 'aartest', version: '0.0.1'