名好难改
名好难改
3月前 · 4 人阅读

一、前言

笔者在做Android SDK开发的过程中,也算从0到1,遇坑填坑了,今天分享的是在封装aar时遇到的那些坑,以及对SDK设计的改进等等。

二、配置清单

1、AndroidManifest,若SDK在配置清单中申请权限,编译时就会报合并重复错误,只能去除主项目中原有的声明。因此,不建议在SDK内部声明,应改为在接入文档中说明,由主项目配置。

2、<application/> 标签,常见默认属性如:android:nameandroid:themeandroid: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"
}

八、结语

今天的分享就到这里了,由于本人水平所限,内容难免错漏,欢迎批评指正!

收藏 0
关键词: sdk android application aar 打包
评论