一、前言
前几天听到盆友在开发sdk,比较好奇,就试了下,这些是我的经验,望大家互相学习,有意见不能保留,这样大家才能互相学习啊
二、配置清单
1、AndroidManifest
,若SDK在配置清单中申请权限,编译时就会报合并重复错误,只能去除主项目中原有的声明。因此,不建议在SDK内部声明,应改为在接入文档中说明,由主项目配置。
2、<application/>
标签,常见默认属性如:android:name
,android:theme
,android:lable
... 如无切实必要,请去除这些属性,避免打包时与主项目冲突。
三、Gradle文件
打包编译重命名,抽取aar+版本号自动重命名并复制到指定目录下
apply plugin: 'com.android.library'static def releaseTime() { return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC")) } android { compileSdkVersion 25 buildToolsVersion '26.0.2' defaultConfig { minSdkVersion 19 targetSdkVersion 25 versionCode 6 versionName "5.1.0" } ... repositories { flatDir { dirs 'libs' } } libraryVariants.all { variant -> if (variant.buildType.name == 'release') { variant.assemble.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 = "/build/aar" copy { from outputFile into outputPath } copy { from outputFile into outputPath rename { fileName + ".aar" } } } } } } } } dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) testImplementation 'junit:junit:4.12' implementation 'com.android.support:appcompat-v7:25.4.0'}
四、资源id命名规范
Values中的colors、strings、styles中的id命名应当注意保持一定的唯一性(如:命名统一加项目前缀),避免与主项目中的资源id冲突,造成SDK中的资源被覆盖,如theme、string等等。
当然,从另一个角度来看,这个特性也可以作为定制UI的一个思路,用主项目中定义的相同资源覆盖掉SDK中的资源属性,从而实现灵活改变SDK的样式。
五、避免创建Application对象
若SDK中定义了Application对象,而主项目也定义了Application或者应用了第三方Application,则需将android:name属性替换掉,才能正常编译,因为一个App只能指定一个Application,若直接替换,则会造成SDK中的Application无法初始化,引起一大波问题。
解决方案有二:
1、避免在SDK中创建Application对象,暴露出一个初始化方法,在主项目的Application相关方法如onCreate()
中注入相关参数执行;
2、若无法避免,则可指定主项目的Application继承自SDK中的内置Application,问题可以解决。
/** * <pre> * author : fdm * time : 2018/03/09 * desc : SDK初始化 * version: 1.0 * </pre> */public class MySDK { private static Context sContext; public MySDK() { } //提供给第三方调用,进行初始化 public static void initSDK(Context context) { sContext = context; initLog(context); } private static void initLog(Context context) { new LogUtil.Builder(context) .setLogSwitch(true) .setGlobalTag("fdm") .setLogHeadSwitch(true) .setLogFilter(LogUtil.D); } public static Context getContext() { return sContext; } }
六、无法将第三方库打包进aar的问题
library打包出来的 AAR ,不会将依赖的第三方库打包进去。这个问题也是由来已久,详情可见: Android Studio how to package single AAR from multiple library projects?
解决方案有两个:
1、将AAR发布到远程仓库,这样gradle依赖下来的时候就会自动依赖第三方库了。
2、在主项目中显式指定SDK中的第三方依赖包,如常见的gson、okhttp等等...
七、混淆问题
在Android开发中,我们一般都会对代码进行混淆后发布,所以在测试SDK时必须考虑到这个情况。
默认情况下,proguard-rules.pro
中的混淆配置是不会被打包进aar中的,所以一般需要在主项目中手动指定混淆规则。
但是,为了提高接入体验,能否将SDK中的混淆配置也打包进aar中,让项目自动配置SDK的混淆文件呢?答案是肯定的,我们可以指定consumerProguardFiles
属性,自定义引入的混淆规则,即可将*.pro
文件打包进入aar
中,项目打包时就会自动合并该配置文件。 值得一提的是该属性只镇对library有效,对app无效。
consumerProguardFiles
配置如下:
defaultConfig { minSdkVersion 17 targetSdkVersion 26 versionCode 1 versionName "1.0" consumerProguardFiles 'proguard-rules.pro'//一行代码解决SDK内部混淆问题 testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"}
原文链接:http://www.apkbus.com/blog-892197-78114.html