productFlavors {
speed {
minSdkVersion 21
}
}
同步项目之后,我们在Android Studio右侧的 Build Variants 中选中 speedDebug 选项即可,如下图所示:
需要注意的是,要注意我们当前项目的实际最低版本,比如它为 18,现在我们开启了 speedDebug,项目编写时就会以 21 为标准,此时,就 需要注意 18 ~ 21 之间的 API,例如我在布局中使用了 21 版本新出的 Material Design 的控件,此时就是没问题的,但实际我们需要对 21 版本以下的对应布局做相应的适配。
此外,我们也可以定义不同的 productFlavors,并且在 src 目录下新建对应的 flavor 名称标识的目录资源文件,以此实现在不同的渠道 APK 中采用不同的资源文件。
10、配置 gradle.properties
通用的配置项如下所示:
// 构建初始化需要执行许多任务,例如java虚拟机的启动,加载虚拟机环境,加载class文件等等,配置此项可以开启线程守护,并且仅仅第一次编译时会开启线程(Gradle 3.0版本以后默认支持)
org.gradle.daemon=true
// 配置编译时的虚拟机大小
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
// 开启并行编译,相当使用了多线程,仅仅适用于模块化项目(存在多个 Library 库工程依赖主工程)
org.gradle.parallel=true
// 最大的优势在于帮助多 Moudle 的工程提速,在编译多个 Module 相互依赖的项目时,Gradle 会按需选择进行编译,即仅仅编译相关的 Module
org.gradle.configureondemand=true
// 开启构建缓存,Gradle 3.5新的缓存机制,可以缓存所有任务的输出,
// 不同于buildCache仅仅缓存dex的外部libs,它可以复用
// 任何时候的构建缓存,设置包括其它分支的构建缓存
org.gradle.caching=true
这里效果比较好一点的配置项就是 配置编译时的虚拟机大小 这项,我们来详细分析下其中参数的含义,如下所示:
- -Xmx2048m:指定 JVM 最大允许分配的堆内存为 2048MB,它会采用按需分配的方式。
- -XX:MaxPermSize=512m:指定 JVM 最大允许分配的非堆内存为 512MB,同上堆内存一样也是按需分配的。
11、配置 DexOptions
我们可以将 dexOptions 配置项中的 maxProcessCount 设定为 8,这样编译时并行的最大进程数数目就可以提升到 8 个。
12、使用 walle 提升打多渠道包的效率
walle 是 Android Signature V2 Scheme 签名下的新一代渠道包打包神器,它在 Apk 中的 APK Signature Block 区块添加了自定义的渠道信息以生成渠道包,因而提高了渠道包的生成效率。此外,它也可以作为单机工具来使用,也可以部署在 HTTP 服务器上来实时处理渠道包 Apk 的升级网络请求,有需要的同学可以参考美团的 walle。
13、设置应用支持的语言
如果应用没有做国际化,我们可以让应用仅仅支持 中文的资源配置,即将 resConfigs 设置为 “zh”。如下所示:
android {
defaultConfig {
resConfigs “zh”
}
}
14、使用增量编译
Gradle 的构建方式通常来说细分为以下 三种:
- 1)、Full Build:全量构建,即从0开始构建。
- 2)、Incremental build java change:增量构建Java改变,修改源代码后的构建,且之前构建过。
- 3)、Incremental build resource change:修改资源文件后的构建,且之前构建过。
在 Gradle 4.10 版本之后便默认使用了增量编译,它会测试自上次构建以来是否已更改任何 gradle task 任务输入或输出。如果还没有,Gradle 会将该任务认为是最新的,因此跳过执行其动作。由于 Gradle 可以将项目的依赖关系分析精确到类级别,因此,此时仅会重新编译受影响的类。如果在更老的版本需要启动增量编译,可以使用如下配置:
tasks.withType(JavaCompile) {
options.incremental = true
}
15、使用循环进行依赖优化(✨)
在 Awesome-WanAndroid 项目的 app moudle 的 build.gradle 中,有将近几百行的依赖代码,如下所示:
dependencies {
implementation fileTree(include: [’*.jar’], dir: ‘libs’)
// 启动器
api files(‘libs/launchstarter-release-1.0.0.aar’)
//base
implementation rootProject.ext.dependencies[“appcompat-v7”]
implementation rootProject.ext.dependencies[“cardview-v7”]
implementation rootProject.ext.dependencies[“design”]
implementation rootProject.ext.dependencies[“constraint-layout”]
annotationProcessor rootProject.ext.dependencies[“glide_compiler”]
//canary
debugImplementation (rootProject.ext.dependencies[“leakcanary-android”]) {
exclude group: ‘com.android.support’
}
releaseImplementation (rootProject.ext.dependencies[“leakcanary-android-no-op”]) {
exclude group: ‘com.android.support’
}
testImplementation (rootProject.ext.dependencies[“leakcanary-android-no-op”]) {
exclude group: ‘com.android.support’
}
…
有没有一种好的方式不在 build.gradle 中写这么多的依赖配置?
有,就是 使用循环遍历依赖。答案似乎很简单,但是要想处理在依赖时遇到的所有情况,并不简单。下面,我直接给出相应的适配代码,大家可以直接使用。
首先,在 app 下的 build.gradle 的依赖配置如下所示:
// 处理所有的 aar 依赖
apiFileDependencies.each { k, v -> api files(v)}
// 处理所有的 xxximplementation 依赖
implementationDependencies.each { k, v -> implementation v }
debugImplementationDependencies.each { k, v -> debugImplementation v }
releaseImplementationDependencies.each { k, v -> releaseImplementation v }
androidTestImplementationDependencies.each { k, v -> androidTestImplementation v }
testImplementationDependencies.each { k, v -> testImplementation v }
debugApiDependencies.each { k, v -> debugApi v }
releaseApiDependencies.each { k, v -> releaseApi v }
compileOnlyDependencies.each { k, v -> compileOnly v }
// 处理 annotationProcessor 依赖
processors.each { k, v -> annotationProcessor v }
// 处理所有包含 exclude 的依赖
implementationExcludes.each { entry ->
implementation(entry.key) {
entry.value.each { childEntry ->
exclude(group: childEntry)
}
}
}
debugImplementationExcludes.each { entry ->
debugImplementation(entry.key) {
entry.value.each { childEntry ->
exclude(group: childEntry.key, module: childEntry.value)
}
}
}
releaseImplementationExcludes.each { entry ->
releaseImplementation(entry.key) {
entry.value.each { childEntry ->
exclude(group: childEntry.key, module: childEntry.value)
}
}
}
testImplementationExclude.each { entry ->
testImplementation(entry.key) {
entry.value.each { childEntry ->
exclude(group: childEntry.key, module: childEntry.value)
}
}
}
androidTestImplementationExcludes.each { entry ->
androidTestImplementation(entry.key) {
entry.value.each { childEntry ->
exclude(group: childEntry.key, module: childEntry.value)
}
}
}
然后,在 config.gradle 全局依赖管理文件中配置好对应名称的依赖数组即可。代码如下所示:
dependencies = [
// base
“appcompat-v7” : “com.android.support:appcompat-v7:${version[“supportLibraryVersion”]}”,
…
]
annotationProcessor = [
“glide_compiler” : “com.github.bumptech.glide:compiler:${version[“glideVersion”]}”,
…
]
apiFileDependencies = [
“launchstarter” :“libs/launchstarter-release-1.0.0.aar”
]
debugImplementationDependencies = [
“MethodTraceMan” : “com.github.zhengcx:MethodTraceMan:1.0.7”
]
…
implementationExcludes = [
“com.android.support.test.espresso:espresso-idling-resource:3.0.2” : [
‘com.android.support’ : ‘support-annotations’
]
]
…
三、Gradle 常用命令
1、Gradle 查询命令
1)、查看主要任务
./gradlew tasks
2)、查看所有任务,包括缓存任务等等
./gradlew tasks --all
2、Gradle 执行命令
1)、对某个module [moduleName] 的某个任务[TaskName] 运行
./gradlew :moduleName:taskName
3、Gradle 快速构建命令
Gradle 提供了一系列的快速构建命令来替代 IDE 的可视化构建操作,如我们最常用的 clean、build 等等。需要注意的是,build 命令会把 debug、release 环境的包都构建出来。
1)、查看构建版本
./gradlew -v
2)、清除 build 文件夹
./gradlew clean
3)、检查依赖并编译打包
./gradlew build
4)、编译并安装 debug 包
./gradlew installDebug
5)、编译并打印日志
./gradlew build --info
6)、编译并输出性能报告,性能报告一般在构建工程根目录 build/reports/profile 下
./gradlew build --profile
7)、调试模式构建并打印堆栈日志
./gradlew build --info --debug --stacktrace
8)、强制更新最新依赖,清除构建后再构建
./gradlew clean build --refresh-dependencies
9)、编译并打 Debug 包
./gradlew assembleDebug
简化版命令,取各个单词的首字母
./gradlew aD
10)、编译并打 Release 的包
./gradlew assembleRelease
简化版命令,取各个单词的首字母
./gradlew aR
4、Gradle 构建并安装命令
1)、Release 模式打包并安装
./gradlew installRelease
2)、卸载 Release 模式包
./gradlew uninstallRelease
3)、debug release 模式全部渠道打包
./gradlew assemble
5、Gradle 查看包依赖命令
1)、查看项目根目录下的依赖
./gradlew dependencies
2)、查看 app 模块下的依赖
./gradlew app:dependencies
3)、查看 app 模块下包含 implementation 关键字的依赖项目
./gradlew app:dependencies --configuration implementation
四、使用 Build Scan 诊断应用的构建过程
在了解 Build Scan 之前,我们需要先来一起学习下旧时代的 Gradle build 诊断工具 Profile report。
1、Profile report
通常情况下,我们一般会使用如下命令来生成一份本地的构建分析报告:
./gradlew assembleDebug --profile
这里,我们在 Awesome-WanAndroid App的根目录下运行这个命令,可以得到四块视图。下面,我们来了解下。
1)、Summary
Gradle 构建信息的概览界面,用于 查看 Total Build Time、初始化(包含 Startup、Settings and BuildSrc、Loading Projects 三部分)、配置、任务执行的时间。如下图所示:
2)、Configuaration
Gradle 配置各个工程所花费的时间,我们可以看到 All projects、app 模块以及其它模块单个的配置时间。如下图所示:
ile
这里,我们在 Awesome-WanAndroid App的根目录下运行这个命令,可以得到四块视图。下面,我们来了解下。
1)、Summary
Gradle 构建信息的概览界面,用于 查看 Total Build Time、初始化(包含 Startup、Settings and BuildSrc、Loading Projects 三部分)、配置、任务执行的时间。如下图所示:
[外链图片转存中…(img-QgChgv5A-1643286492326)]
2)、Configuaration
Gradle 配置各个工程所花费的时间,我们可以看到 All projects、app 模块以及其它模块单个的配置时间。如下图所示: