鸿洋推荐:实际生产中的 Android SDK开发总结(七)依赖原则与打包方法

分享该系列第六篇干货,这是作者实际生产中的 SDK 经验,非常宝贵的经验,系列一共七篇,这是最后一篇,记得关注前文哦。

Android SDK开发艺术探索系列基于实际生产中的业务型SDK开发实践经验,具有一定的实战性与技术性,不仅包含一定业务背景下的经验之谈,还系统性地介绍了一款第三方SDK的开发过程以及相关技术的选型。

在这个系列中,你不仅能了解到如何开发一款第三方SDK,还能学习到通用的Android开发知识、软件工程思想,甚至一些奇奇怪怪的知识。

PS: 本文在开源项目:https://github.com/xieyuliang/Note-Android中已收录,里面包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中……

前面,我们介绍了 SDK 开发的:

开篇与设计
Exception or ErrorCode
初始化
个性化配置
安全与校验
压缩与优化

前文指路↓↓↓
实际生产中的 Android SDK开发总结(一)https://www.jianshu.com/p/ff9362d243a2

实际生产中的 Android SDK开发总结(二)https://www.jianshu.com/p/362116211655

实际生产中的 Android SDK开发总结(三)https://www.jianshu.com/p/919a54601310

实际生产中的 Android SDK开发总结(四)https://www.jianshu.com/p/133097271280

实际生产中的 Android SDK开发总结(五)https://www.jianshu.com/p/56bfd38920ba

实际生产中的 Android SDK开发总结(六)https://www.jianshu.com/p/2252b318b7b9

依赖原则与打包方法

一、基本配置

1.1、Module配置

创建一个library module这个很简单,Android Studio直接new一个Project后,再new一个Android Library就可以了。

app module用于模拟调试;library module 用于编写SDK代码,生成jar/aar。

模板配置非全部由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'
}

1.2、如何打一个aar包

有图有真相:

  1. 双击gradle脚本assembleRelease,执行正式aar编译生成过程;

  2. 编译完成,可以看到outputs目录下自动生成了一个aar文件,同时我们的脚本也生效了,将其复制到了指定的目录下(这里可以做一下自动版本命名之类的工作)

没错,就是这么简单,到这里就生成了我们要发布的SDK!

二、依赖原则

2.1、尽量避免第三方库的依赖

在本系列开篇文章中提到了SDK开发的两个原则:

一是:最小可用性原则,即用最少的代码,如无必要勿增实体;二是:最少依赖性原则,即用最低限度的外部依赖,如无必要勿增依赖。

SDK开发中,需要尽量避免依赖第三方库,使用通用的Android SDK自带的官方库能满足需求即可,以免引起不必要的冲突或者三方库不要放到lib包下,默认打包进去封装过程中的aar二次打包问题;

比如,不要为了一个简单的JSON数据转换就引入Fastjson 、Gson之类的第三方json解析转换库。

如果确实因为项目需要,要引入一些开源库,可以通过源码集成的形式引入,再更改一下包名,避免集成冲突。

2.2、AndroidManifest无关属性剔除

如无必要,请保证 SDK Module中的AndroidManifest 配置简洁,剔除无关属性,如<supports-screens、标签中的无意义字段。

2.3、SDK依赖项配置区别与原则

在 dependencies 代码块内,可以配置不同的依赖指令,对应不同的编译行为。如compileOnly、implementation、api的介绍以及配置原则。

三、如何解决组件依赖冲突

当我们集成的各种SDK包含相同依赖的时候,有可能产生版本冲突,此时可以通过如下方法进行配置解决。

3.1、强制使用指定版本

grconfigurations.all {
    resolutionStrategy {
        //强制使用某些版本的依赖
        force 'com.android.support:support-v4:26.1.0','com.android.support:appcompat-v7:26.1.0'
    }
}

配置后查看依赖版本信息如下:

3.2、排除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开发探索系列到此为止,后续可能会出一些番外篇。希望整个系列下来对大家在SDK开发或者集成中能有所启发,感谢大家!

最后

本文在开源项目:https://github.com/xieyuliang/Note-Android中已收录,里面包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值