前言:我们在开发sdk时,经常会需要将产物aar上传到maven库中,而sdk又需要依赖一些公共模块或者第三方库,这个时候简单的使用implementation
就会出现问题,一是无法将依赖的公共模块打包进sdk中,二是将依赖的第三方库比如gson打包进aar后,别人依赖时又会出现版本冲突(duplicated class),如果不将第三方库打进aar,别人依赖时又必须单独引入,很是麻烦。本文介绍了一种比较优雅的方式,解决了这样的问题。
直接上最终解决方案:
- 在项目的build.gradle中添加fataar依赖,注意要加到文件的最上方,否则会导致编译不过:
repositories {
dependencies {
classpath 'com.github.kezong:fat-aar:1.3.6'
}
}
- 在lib的module模块的build.gradle中这样添加依赖:
plugins {
id 'com.android.library'
}
apply plugin: 'com.kezong.fat-aar'
apply from: 'upload.gradle'
....
....
dependencies {
implementation "com.squareup.okhttp3:okhttp:$okhttpVersion"
api "com.google.code.gson:gson:$gsonVersion"
if(isSdkMode.toBoolean()){
embed project(":base")
} else {
api project(":base")
}
}
使用embed
替换之前的implementation
或者api
就可以将base模块打包进aar中了。
- upload.gradle是用来将lib库打包上传的maven的工具,主要解决办法也是在这个文件里实现的。先上代码:
apply plugin: 'maven-publish'
def USERNAME = "xiaoqiang"
def PASSWORD = "xiaoqiang"
def REPOSITORY_URL = "https://xiaoqiang.com/test-snapshot/"
publishing {
publications {
Production(MavenPublication) {
groupId = "com.example.xiaoqiang"
artifactId = "xiaoqiang"
version = "$sdkVersion"
afterEvaluate { artifact(tasks.getByName("bundleReleaseAar")) }
pom.withXml {
def dependencies = asNode().appendNode('dependencies')
def dependency = dependencies
.appendNode("dependency")
dependency.appendNode("groupId", "com.squareup.okhttp3")
dependency.appendNode("artifactId", "okhttp")
dependency.appendNode("version", "$okhttpVersion")
dependency = dependencies
.appendNode("dependency")
dependency.appendNode("groupId", "com.google.code.gson")
dependency.appendNode("artifactId", "gson")
dependency.appendNode("version", "$gsonVersion")
}
}
}
repositories {
maven {
url REPOSITORY_URL
credentials {
username = USERNAME
password = PASSWORD
}
allowInsecureProtocol true
}
}
}
这里需要注意的是:snapshot版本的版本名字必须带snapshot,否则会上传失败。这样做的原理其实就是将第三方依赖写进aar的pom文件中,别人以maven形式远程依赖我们的sdk时,gradle会自动拉下来pom文件中的依赖版本。另外,如果外部也依赖了gson的话,版本不一致也不会出现冲突,外部引用用的是外部的版本,sdk用的是pom文件中的版本。
- 一般情况下,app模块会作为demo调试用,这个时候在app的build.gradle中可以这样配置:
dependencies {
//引用 sdk
if (sdkMode.toBoolean()) {
implementation("com.example.xiaoqiang:xiaoqiang:$sdkVersion")
} else {
implementation project(":sdk")
}
}
当然,在添加依赖时,也要在setting.gradle中声明库地址,包括aar发布的地址以及依赖的第三方库的地址:
repositories {
google()
mavenCentral()
maven {
allowInsecureProtocol true
url 'http://****.*****.com/repository/maven-public/'
}
maven {
url 'https://maven.aliyun.com/repository/public/'
}
}
其中sdk的版本号及第三方依赖的版本我都抽离出来放在gradle.properties文件中了,因为这里可以定义一些全局变量,这样在每次发布aar时只需要在这一个文件里修改变量的值就可以啦。
sdkMode=true
sdkVersion=0.0.1-SNAPSHOT
gsonVersion=2.10
okhttpVersion=4.10.0
到此已经全部配置完成。改一下sdkVersion的值,在gradle点一下publish就可以将sdk上传到maven库了,然后在sync一下,就可以把刚刚上传的sdk拉下来验证了。注意:sdkMode的值在publish时必须是true。 本地调试时,只需要将sdkMode改为false就可以自动依赖本地模块了。