赞
踩
工程构建工具从古老的 mk、make、cmake、qmake, 再到成熟的 ant、maven、ivy,最后到如今互联网时代的 sbt、gradle,经历了长久的历史演化与变迁。
Gradle 作为一款新生代的构建工具无疑是有它自身的巨大优势的,因此,掌握好 Gradle 构建工具的各种使用姿势与使用场景其重要性不言而喻。
此外,Gradle 已经成为 高级 Android 知识体系 必不可少的一部分。因此,掌握 Gradle,提升自身 自动化构建技术的深度, 能让我们更加地 如虎添翼。
主要基于如下 三点 原因:
通常来说,Gradle 一次完整的构建过程通常分成如下 三个部分:
掌握 Gradle 构建提速的技巧能够帮助我们节省大量的编译构建时间,并且,依赖模块越多且越大的项目节省出来的时间越多,因此是一件投入产出比相当大的事情。
将 Gradle 和 Android Gradle Plugin 的版本升至最新,所带来的的构建速度的提升效果是显而易见的,特别是当之前你所使用的版本很低的时候。
打开 Android Studio 的离线模式后,所有的编译操作都会走本地缓存,毫无疑问,这将会极大地缩短编译时间。
在默认情况下, AS 的最大堆内存为 1960MB,我们可以选择 Help => Edit Custom VM Options,此时,会打开一个 studio.vmoptions 文件,我们将第二行的 -Xmx1960m 改为 -Xmx3g 即可将可用内存提升到 3GB。
过多的 Moudle 会使项目中 Module 的依赖关系变得复杂,Gradle 在编译构建的时候会去检测各个 Module 之间的依赖关系,然后,它会花费大量的构建时间帮我们梳理这些 Module 之间的依赖关系,以避免 Module 之间相互引用而带来的各种问题。除了删除不必要的 Moudle 或合并部分 Module 的方式外,我们也可以将稳定的底层 Module 打包成 aar,上传到公司的本地 Maven 仓库,通过远程方式依赖。
在 Android Studio 中提供了供了自动检测失效文件和删除的功能,即 Remove Unused Resource 功能,操作路径如下所示:
右键 => 选中 Refactor => 选中Remove Unused Resource => 直接点击REFACTOR
需要注意的是,这里不需要将 Delete unused @id declarations too 选中,如果你使用了 databinding 的话,可能会编译失败。
一般的优化步骤有如下 三步:
例如,我在 Awesome-WanAndroid 项目中就使用到了这种技巧,在依赖 LeakCanary 时,发现它包含有 support 包,因此,我们可以使用 exclude 将它排除掉,代码如下所示:
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'
}
// 仅在debug包启用BlockCanary进行卡顿监控和提示的话,可以这么用
debugImplementation 'com.github.markzhai:blockcanary-android:1.5.0'
当第一个开发引入了新库或者更新版本之后,公司的 Maven 仓库中就会缓存对应的库版本,通过这样的方式,其他开发同事就能够在项目构建时直接从公司的 Maven 仓库中拿到缓存。
这样,我们就可以避免因使用 MutliDex 而拖慢 build 速度。在主 Moudle 中的 build.gradle 中加入如下代码:
productFlavors {
speed {
minSdkVersion 21
}
}
同步项目之后,我们在Android Studio右侧的 Build Variants 中选中 speedDebug 选项即可,如下图所示:
需要注意的是,要注意我们当前项目的实际最低版本,比如它为 18,现在我们开启了 speedDebug,项目编写时就会以 21 为标准,此时,就 需要注意 18 ~ 21 之间的 API,例如我在布局中使用了 21 版本新出的 Material Design 的控件,此时就是没问题的,但实际我们需要对 21 版本以下的对应布局做相应的适配。
此外,我们也可以定义不同的 productFlavors,并且在 src 目录下新建对应的 flavor 名称标识的目录资源文件,以此实现在不同的渠道 APK 中采用不同的资源文件。
通用的配置项如下所示:
// 构建初始化需要执行许多任务,例如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
这里效果比较好一点的配置项就是 配置编译时的虚拟机大小 这项,我们来详细分析下其中参数的含义,如下所示:
我们可以将 dexOptions 配置项中的 maxProcessCount 设定为 8,这样编译时并行的最大进程数数目就可以提升到 8 个。
walle 是 Android Signature V2 Scheme 签名下的新一代渠道包打包神器,它在 Apk 中的 APK Signature Block 区块添加了自定义的渠道信息以生成渠道包,因而提高了渠道包的生成效率。此外,它也可以作为单机工具来使用,也可以部署在 HTTP 服务器上来实时处理渠道包 Apk 的升级网络请求,有需要的同学可以参考美团的 walle。
如果应用没有做国际化,我们可以让应用仅仅支持 中文的资源配置,即将 resConfigs 设置为 "zh"。如下所示:
android {
defaultConfig {
resConfigs "zh"
}
}
Gradle 的构建方式通常来说细分为以下 三种:
在 Gradle 4.10 版本之后便默认使用了增量编译,它会测试自上次构建以来是否已更改任何 gradle task 任务输入或输出。如果还没有,Gradle 会将该任务认为是最新的,因此跳过执行其动作。由于 Gradle 可以将项目的依赖关系分析精确到类级别,因此,此时仅会重新编译受影响的类。如果在更老的版本需要启动增量编译,可以使用如下配置:
tasks.withType(JavaCompile) {
options.incremental = true
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。