一、前言
本篇是Android SDK开发艺术探索系列的第七篇文章,也是本系列的终篇。简单介绍了SDK开发中关于SDK开发配置、组件依赖原则、组件冲突的解决方法,探索SDK开发中的依赖原则与打包方法。
系列文章:
Android SDK开发艺术探索(二)Exception or ErrorCode
二、基本配置
2.1、Module配置
创建一个library module这个很简单,Android Studio直接new一个Project后,再new一个Android Library就可以了。
app module用于模拟调试;library module 用于编写SDK代码,生成jar/aar。
library module下的build.gradle模板配置:
模板配置非全部由Android Studio自动生成,加入了一些通用的基础的SDK开发相关配置作为参考。要点如下:
gradle下自定义获取当前时间的方法;
自定义混淆规则consumerProguardFiles;
显式限定sdk支持的arm架构指令集,配置abiFilters;
gradle配置引用相对路径下的签名文件;
buildTypes针对编译本module时的相关配置说明;
自动提取编译生成的aar文件,重命名后自动复制到app
module下的libs目录,方便调试验证与发布SDK。
//区别于application,这意味着该module将被视为library
apply plugin: 'com.android.library'
//自定义的一个方法,用来获取当前时间
static def releaseTime() {
return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}
android {
compileSdkVersion 29
buildToolsVersion "29.0.3"
defaultConfig {
minSdkVersion 21
targetSdkVersion 29
versionCode 1
versionName "1.0"
consumerProguardFiles "proguard-rules.pro"//配置自定义的混淆规则,该字段下的混淆规则将作用于集成该SDK的APP
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
ndk {
abiFilters 'armeabi-v7a','arm64-v8a'//显式限定sdk支持的arm架构指令集
}
}
signingConfigs {
release {
storeFile file("../key/mylib.jks")//相对路径下的签名文件
storePassword "Android_2333"
keyAlias "key-sdk"
keyPassword "Android_2333"
}
}
buildTypes {
release {
minifyEnabled true
shrinkResources false//sdk module编译时,不支持设置shrinkResources为true
signingConfig signingConfigs.release
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//编译本module时参与混淆配置的文件
}
debug {
minifyEnabled false
shrinkResources false //sdk module编译时,不支持设置shrinkResources为true
signingConfig signingConfigs.release
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//编译本module时参与混淆配置的文件
}
}
//自动提取编译生成的aar文件,重命名,最后自动复制到appmodule下的libs目录,方便调试验证。
libraryVariants.all { variant ->
if (variant.buildType.name == 'release') {
variant.assembleProvider.get().doLast {
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('release.aar')) {
// def fileName = "${project.name}-release-${android.defaultConfig.versionName}-${releaseTime()}"
def outputPath = "../mylib/build/aar"
def libPath = "../app/libs"
copy {
from outputFile
into outputPath
// rename { fileName + ".aar" }
}
//直接复制到App的libs目录下,方便调试
copy {
from outputFile
into libPath
}
}
}
}
}
}
}
dependencies {
//这句话代表集引入libs目录下的所有jar包
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation 'com.android.support:support-v4:28.0.0'
implementation 'com.android.support:appcompat-v7:28.0.0'
}
2.2、如何打一个aar包
有图有真相:
- 双击gradle脚本assembleRelease,执行正式aar编译生成过程;
- 编译完成,可以看到outputs目录下自动生成了一个aar文件,同时我们的脚本也生效了,将其复制到了指定的目录下(这里可以做一下自动版本命名之类的工作)
没错,就是这么简单,到这里就生成了我们要发布的SDK!
三、依赖原则
3.1、尽量避免第三方库的依赖
在本系列开篇文章中提到了SDK开发的两个原则:
一是:最小可用性原则,即用最少的代码,如无必要勿增实体; 二是:最少依赖性原则,即用最低限度的外部依赖,如无必要勿增依赖。
SDK开发中,需要尽量避免依赖第三方库,使用通用的Android SDK自带的官方库能满足需求即可,以免引起不必要的冲突或者三方库不要放到lib包下,默认打包进去封装过程中的aar二次打包问题;
比如,不要为了一个简单的JSON数据转换就引入Fastjson 、Gson之类的第三方json解析转换库。
如果确实因为项目需要,要引入一些开源库,可以通过源码集成的形式引入,再更改一下包名,避免集成冲突。
3.2、AndroidManifest无关属性剔除
如无必要,请保证 SDK Module中的AndroidManifest 配置简洁,剔除无关属性,如<supports-screens、标签中的无意义字段。
3.3、SDK依赖项配置区别与原则
在 dependencies 代码块内,可以配置不同的依赖指令,对应不同的编译行为。如compileOnly、implementation、api的介绍以及配置原则。
四、如何解决组件依赖冲突
当我们集成的各种SDK包含相同依赖的时候,有可能产生版本冲突,此时可以通过如下方法进行配置解决。
4.1、强制使用指定版本
grconfigurations.all {
resolutionStrategy {
//强制使用某些版本的依赖
force 'com.android.support:support-v4:26.1.0','com.android.support:appcompat-v7:26.1.0'
}
}
配置后查看依赖版本信息如下:
4.4、排除SDK中的指定模块
排除某SDK下指定module的依赖
dependencies {
implementation('some-library') {
//排除依赖'some-library'中的指定依赖
exclude group: 'com.android.support', module: 'support-v4'
exclude group: 'com.android.support', module: 'appcompat-v7'
}
}
排除所有SDK下指定module的依赖
android {
...
configurations.all {
//全局排除SDk中的指定依赖
exclude group: 'com.android.support', module: 'support-v4'
exclude group: 'com.android.support', module: 'appcompat-v7'
}
...
}
五、结语
本篇简单介绍了SDK开发与集成过程中的依赖原则与打包方法,包括如何打包aar、基本依赖原则、组件依赖冲突的解决方法。Android SDK开发艺术探索系列到此为止,后续可能会出一些番外篇。希望整个系列下来对大家在SDK开发或者集成中能有所启发,感谢大家!
最后,如果本篇文档对您的开发有所帮助或启发,点赞/关注/分享三连就是对作者持续创作最好的激励,感谢支持!