Android|Android 开发之 Gradle那些事儿(三)

自定义构建出的文件名
在android代码块下,使用注入替换的方式,可以自定义构建出的文件名,比每次都出来默认的app-debug.apk或者app-release.apk要友好且清晰。具体代码如下:

//自定义生成的apk名称 applicationVariants.all { variant -> variant.outputs.each { output -> if (!variant.buildType.name.equals('debug')) { def outputFile = output.outputFile //这里修改文件名 def fileName = "GradleDemo-V"+defaultConfig.versionCode+"-"+buildTime()+"-"+getSvnRevision()+".apk" output.outputFile = new File(rootProject.buildDir.path, fileName) } } }

效果如图:

Android|Android 开发之 Gradle那些事儿(三)
文章图片
这里写图片描述 多渠道打包
我个人不建议在gradle里用最古老的多渠道打包方法(清单文件里建meta-data,再用productFlavors里面配各种渠道值来动态替换清单文件里的渠道号占位变量。)
原因很明显:配置麻烦,构建非常非常慢,打出来20个包估计得半小时。
我个人也不建议在gradle里直接配 packNg或者walle,因为我个人认为打包生成的文件,本质上是一个压缩包,对于一个压缩包的处理或者生成一堆压缩包,不应该是gradle的工作。我们应该把 构建出安装包 和 一个包分身出多个 这两个作为不同类型的任务(比如我们可以把多渠道分身的任务交给运营或者测试,哈哈哈,可以减轻我们任务节约我们的时间啦,也不用每次给他们花好长时间发几十个包)
我个人建议使用packNg、AndroidMultiChannelBuildTool 或者 walle 的命令行工具在电脑上单独做分身多渠道的任务。团队分享内我已经写了相关教程以及批处理脚本。(另外随着Android7.0的出现,我们推荐使用walle,因为它速度快,使用方便,支持对v2签名包的分身多渠道打包)
【Android|Android 开发之 Gradle那些事儿(三)】多模块组件化配置
在gradle.properties配置一个isModule配置项,取值为true或false。
true代表使用组件化模式,有些独立的模块可以单独拎出来编译打包或者单独做单元测试,不同模块可以分开维护。
false代表集成模式,还是以app模块作为工程的主模块,主模块依赖各个业务模块(都作为library)。

Android|Android 开发之 Gradle那些事儿(三)
文章图片
这里写图片描述
在独立出业务模块的build.gradle里,读取isModule配置值,做不同的模块配置选项
Android|Android 开发之 Gradle那些事儿(三)
文章图片
这里写图片描述 Android|Android 开发之 Gradle那些事儿(三)
文章图片
这里写图片描述 对于各模块的build.gradle除了读取isModule做不同配置外,还有一个比较方便的方案是:把各个模块的build.gradle公共配置,抽到一个公共配置文件里,方便统一修改和统一管理,在各模块的build.gradle中使用apply from:读取(缺点:必须使用AS的Project视图,才能查看到我们的公共配置文件)。

Android|Android 开发之 Gradle那些事儿(三)
文章图片
这里写图片描述
我们在项目更目录下新建CommonConf文件夹,添加modulesCommonConfig.gradle,在modules2中apply。
实际运行效果图:

Android|Android 开发之 Gradle那些事儿(三)
文章图片
这里写图片描述 打开不同模块的app:

Android|Android 开发之 Gradle那些事儿(三)
文章图片
app主模块 Android|Android 开发之 Gradle那些事儿(三)
文章图片
module2模块 关于组件化模式和集成模式清单文件的问题:
当独立模块作为一个独立组件编译运行时(com.android.application),它是要有入口activity的;相反如果用集成模式编译它将作为主模块依赖的库(com.android.library),它的清单文件和资源将会在编译打包时做混合,如果有了不同的application属性或者多个入口activity,就会冲突报错。
但是我们如果每次都去手动修改清单文件,这将是很麻烦的,我们可以创建两个有差异的清单文件,一个给组件化模式用,一个给集成模式用。然后在模块的build.gradle中,根据isModule标志,设定使用不同的清单文件。
例子如下(可以把这个代码块写在每个模块的build.gradle里,也可以写在各模块的公共配置文件里,然后用apply from:读取使用):

Android|Android 开发之 Gradle那些事儿(三)
文章图片
这里写图片描述
我会把Demo地址添加在文章的最后。
一些杂项配置
compileOptions { //指定编译用的java版本 sourceCompatibility JavaVersion.VERSION_1_7 targetCompatibility JavaVersion.VERSION_1_7 }dexOptions { //让它不要对Lib做preDexing preDexLibraries = false //开启incremental dexing,优化编译效率,这个功能android studio默认是关闭的 incremental true //增加java堆内存大小 javaMaxHeapSize "4g" }//默认的一些文件路径的配置 sourceSets { main { assets.srcDirs = ['assets']//资源文件 jni.srcDirs 'src/main/jni'//jni文件 jniLibs.srcDir 'src/main/jniLibs' //jni库 } } packagingOptions { //打包排除掉,不想添加到apk中的文件 exclude 'META-INF/DEPENDENCIES.txt' exclude 'META-INF/LICENSE.txt' exclude 'META-INF/NOTICE.txt' exclude 'META-INF/NOTICE' exclude 'META-INF/LICENSE' exclude 'META-INF/DEPENDENCIES' exclude 'META-INF/notice.txt' exclude 'META-INF/license.txt' exclude 'META-INF/dependencies.txt' exclude 'META-INF/LGPL2.1' exclude 'META-INF/ASL2.0' }

dependencies代码块
dependencies称作依赖配置,一般可以配置三种:依赖本地库文件,依赖远程库文件,依赖本地工程模块
分别示例如下:
compile fileTree(dir: 'libs', include: '*.jar') provided fileTree(dir: '../honjane-demo-library/libs', include: '*.jar')//依赖本地jar compile(name: 'liblivenessdetector2-release', ext: 'aar') compile(name: 'lib-1.1', ext: 'aar')//依赖本地aarcompile 'com.jakewharton:butterknife:8.2.1' compile 'com.squareup.okhttp3:okhttp:3.4.1'//依赖远程库if (isModule.toBoolean()) { compile project(':mylibrary') } else { compile project(':module2') compile project(':module3') compile project(':module4') compile project(':module5') }//依赖本地工程模块

关于Gradle的介绍就到这里啦,欢迎大家一起讨论。
项目地址:github
项目地址:github
项目地址:github
重要的事情说三遍
谢谢大家。完结撒花

Android|Android 开发之 Gradle那些事儿(三)
文章图片
这里写图片描述

    推荐阅读