缓存 Android 项目
虽然 Android 以 Java 工具链为基础,但它与纯 Java 项目之间仍然存在一些重大差异;这些差异会影响任务的可缓存性。对于包含 Kotlin 源代码(因此使用 kotlin-android
插件)的 Android 项目来说,情况更是如此。
消歧义
本指南介绍的是 Gradle 的构建缓存,但您可能也听说过 Android 构建缓存。它们是不同的东西。Android 缓存是 Android 插件中某些任务的内部缓存,最终将被原生 Gradle 支持取代。
为什么要使用构建缓存?
构建缓存可以显著提高 Android 项目的构建性能,在许多情况下可以提高 30-40%。Android Gradle 插件提供的许多编译和组装任务都是可缓存的,并且随着每次新迭代,更多任务变得可缓存。
更快的 CI 构建
CI 构建特别受益于构建缓存。典型的 CI 构建从 clean
开始,这意味着预先存在的构建输出将被删除,并且构成构建的所有任务都不会是 UP-TO-DATE
。但是,这些任务中的许多可能在之前的 CI 构建中使用完全相同的输入运行过,从而填充了构建缓存;这些先前运行的输出可以安全地重复使用,从而显着提高构建性能。
将 CI 构建重复用于本地开发
当你开始工作的那天登录时,你的第一个任务通常是拉取主分支,然后运行构建(Android Studio 可能会执行后者,无论你是否要求它)。假设所有合并到主分支的代码都在 CI 上构建(最佳实践!),你可以预期当天第一次本地构建将从 Gradle 的远程缓存中获得比平时更大的收益。CI 已经构建了这个提交——为什么要重新做这项工作呢?
Android Gradle 插件和 Gradle 构建工具
在优化构建时,你应该始终做的第一件事是确保你使用的是 Android Gradle 插件和 Gradle 构建工具的最新稳定支持版本。在撰写本文时,它们分别是 3.3.0 和 5.0。这些工具的每个新版本都包含许多性能改进,其中最重要的是对构建缓存的改进。
注解处理器和 Kotlin
针对纯 Java 项目的 上述建议 也适用于 Android 项目。但是,如果您在使用 Kotlin 和 kotlin-kapt 插件时使用注解处理器(例如 Dagger2 或 Butterknife),您应该知道在 Kotlin 1.3.30 之前,kapt 默认情况下不会被缓存。
您可以选择启用它(建议这样做),方法是在构建脚本中添加以下内容
pluginManager.withPlugin("kotlin-kapt") {
configure<KaptExtension> { useBuildCache = true }
}
plugins.withId("kotlin-kapt") {
kapt.useBuildCache = true
}
仪器测试执行(即 Espresso 测试)
Android 仪器测试(DeviceProviderInstrumentTestTask
),通常称为“Espresso”测试,也不可缓存。Google Android 团队也正在努力使此类测试可缓存。请参阅 此问题。
Lint
Android 的 Lint
任务的用户都知道使用它会带来巨大的性能损失,但也知道它对于在 Android 项目中查找常见问题是必不可少的。目前,此任务不可缓存。计划在 Android Gradle 插件 3.5 发布时使此任务可缓存。这也是始终使用最新版本的 Android 插件的另一个理由!
Fabric 插件和 Crashlytics
用于集成 Crashlytics 崩溃报告工具(以及其他工具)的 Fabric 插件非常流行,但在构建过程中会带来一些沉重的性能损失。这是因为需要为您的应用程序的每个版本提供唯一的标识符,以便它可以在 Crashlytics 仪表板中识别。实际上,Crashlytics 的默认行为是将“每个版本”等同于“每个构建”。这会破坏 增量构建,因为每个构建都是唯一的。它还会破坏构建中某些任务的可缓存性,原因相同。这可以通过简单地在“调试”构建中禁用 Crashlytics 来解决。您可以在 Crashlytics 文档 中找到相关说明。
如果您使用的是 Kotlin DSL,则参考文档中描述的修复方法无法直接使用;请参阅下面的解决方法。 |
Kotlin DSL
如果您使用的是 Kotlin DSL,则参考文档中描述的修复方法无法直接使用;这是由于该 Kotlin DSL 与 Fabric 插件之间存在不兼容性。有一个简单的解决方法,基于 Kotlin DSL 入门指南中的建议。
在您应用 io.fabric
插件的模块中创建一个名为 fabric.gradle
的文件。此文件(称为脚本插件)应包含以下内容
plugins.withId("com.android.application") { // or "com.android.library" android.buildTypes.debug.ext.enableCrashlytics = false }
然后,在模块的 build.gradle.kts
文件中,应用此脚本插件
apply(from = "fabric.gradle")