自 2020 年底,Android Gradle 插件 (AGP) 已经开始使用新的版本号规则,其版本号将与 Gradle 主要版本号保持一致,因此 AGP 4.2 之后的版本为 7.0 (目前最新的版本为 7.2)。在更新 Android Studio 时,您可能会收到一并将 Gradle 更新为最新可用版本的提示。为了获得最佳性能,建议您使用 Gradle 和 Android Gradle 插件这两者的最新版本。Android Gradle 插件的 7.0 版本更新带来了许多实用的特性,本文将着重为您介绍其中的 Gradle 性能改进、配置缓存和插件扩展等方面的内容。
如果您更喜欢通过视频了解此内容,请在 点击此处 查看。
Gradle 的性能改进
Kotlin 符号处理优化
Kotlin 符号处理 (Kotlin Symbol Processing,简称 KSP) 是 kapt (Kotlin annotation processing tool) 的替代品,它为 Kotlin 语言带来了一流的注解处理能力,处理速度最快可以达到 kapt 的两倍。目前已经有不少知名的软件库提供了兼容 KSP 的注解处理器,比如 Room、Moshi、Kotishi 等等。因此我们建议,当您的应用中所用到的各种注解处理器都支持 KSP 时,应该尽快从 kapt 迁移到 KSP。
非传递性 R 类
启用非传递性 R 类 (non-transitive R-class) 后,您应用中的 R 类将只会包含在子项目中声明的资源,依赖项中的资源会被排除在外。这样一来,子项目中的 R 类大小将会显著减少。
这一改动可以在您向运行时依赖项中添加新资源时,避免重新编译下游模块。在这种场景下,可以给您的应用带来 40% 的性能提升。另外,在清理构建产物时,我们发现性能有 5% 到 10% 的改善。
您可以在 gradle.properties 文件中添加下面的标记:
android.nonTransitiveRClass=true
△ 在 gradle.properties 中开启非传递性 R 类功能
您也可以在 Android Studio Arctic Fox 及以上版本使用重构工具来启用非传递性 R 类,具体需要您运行 Android Studio 菜单栏的 Refactor --> Migrate to Non-transitive R Classes。这种方法还可以在必要时帮助您修改相关源代码。目前,AndroidX 库已经启用此特性,因此 AAR 阶段的产物中将不再包含来自传递性依赖项的资源。
Lint 性能优化
从 Android Gradle 插件 7.0 版本开始,Lint 任务可以显示为 “UP-TO-DATE”,即如果模块的源代码和资源没有更改,那么就不需要对该模块进行 Lint 分析任务。您需要在 build.gradle 中添加选项:
// build.gradle
android {
...
lintOptions {
checkDependencies true
}
}
△ 在 build.gradle 中开启 lint 性能优化
如此一来,Lint 分析任务就可以在各个模块中并行执行,从而显著提升 Lint 任务运行的速度。
从 Android Gradle 插件的 7.1.0-alpha 13 版本开始,Lint 分析任务兼容了 Gradle 构建缓存 (Gradle build cache),它可以通过 复用其他构建的结果来减少新构建的时间:
△ 不同 AGP 版本中 Lint 时间比较
我们在一个演示项目中开启了 Gradle 构建缓存并设置 checkDependencies 为 true,然后分别使用 AGP 4.2、7.0 和 7.1 进行构建。从上图中可看出,7.0 版本的构建速度是 4.2 的两倍;并且在使用 AGP 7.1 时,由于所有 Lint 分析任务都命中了缓存而带来了更加显著的速度提升。
您不但可以直接通过更新 Android Gradle 插件版本获得更好的 Lint 性能,还能通过一些配置来进一步提升效率。其中一种方法是使用可缓存的 Lint 分析任务。要启用 Gradle 的构建缓存,您需要在 gradle.properties 文件中开启下面的标记 (参见 Build Cache):
org.gradle.caching=true
△ 在 gradle.properties 中开启 Gradle 构建缓存
另一种可改进 Lint 分析任务性能的方法是,在您条件允许的情况下给 Lint 分配更多的内存。
同时,我们建议您在 应用模块 的 Gradle 配置中为 lintOptions 块添加:
checkDependencies true
△ 在模块的 build.gradle 中添加 checkDependencies 标记
虽然这样不能让 Lint 分析任务更快执行,但能够让 Lint 在分析您指定应用时捕捉到更多问题,并且为整个项目生成一份 Lint 报告。
Gradle 配置缓存</