缓存 Android 项目
虽然 Android 的基础是 Java 工具链,但与纯 Java 项目相比,仍存在一些显著差异;这些差异会影响任务的可缓存性。对于包含 Kotlin 源代码(因此使用 kotlin-android
插件)的 Android 项目来说,更是如此。
消除歧义
本指南是关于 Gradle 的构建缓存的,但您可能也听说过 Android 构建缓存。这些是不同的东西。Android 缓存是 Android 插件中某些任务的内部缓存,最终将被移除,转而支持原生 Gradle 支持。
为什么要使用构建缓存?
构建缓存可以
更快的 CI 构建
CI 构建特别受益于构建缓存。典型的 CI 构建以 clean
开头,这意味着现有的构建输出被删除,并且构成构建的任务都不会是 UP-TO-DATE
。但是,这些任务中的许多很可能已经在之前的 CI 构建中以完全相同的输入运行过,从而填充了构建缓存;这些先前运行的输出可以安全地重用,从而显著提高构建性能。
将 CI 构建用于本地开发
当您一天开始工作时,第一项任务通常是拉取主分支,然后运行构建(Android Studio 可能会自动执行后者,无论您是否要求)。假设主分支的所有合并都在 CI 上构建(最佳实践!),那么您就可以期望当天第一次本地构建能够从 Gradle 的
Android Gradle 插件
Android Studio 用户应使用最新的 Android Gradle 插件,以确保兼容性并受益于新版本中的性能改进。
在优化构建时,您首先应该始终确保使用的是最新稳定、受支持的 Android Gradle 插件和 Gradle 构建工具版本。在撰写本文时,它们分别是 3.3.0 和 5.0。这些工具的每个新版本都包含许多性能改进,其中最重要的就是构建缓存。
注解处理器和 Kotlin
上面针对纯 Java 项目的建议也适用于 Android 项目。但是,如果您将注解处理器(例如 Dagger2 或 Butterknife)与 Kotlin 和 kotlin-kapt 插件结合使用,您应该知道在 Kotlin 1.3.30 之前,kapt 默认不缓存。
您可以通过向构建脚本添加以下内容来选择启用它(推荐)
pluginManager.withPlugin("kotlin-kapt") {
configure<KaptExtension> { useBuildCache = true }
}
plugins.withId("kotlin-kapt") {
kapt.useBuildCache = true
}
单元测试执行
与纯 Java 项目中的单元测试一样,Android 项目中的等效测试任务(AndroidUnitTest
)从 Android Gradle 插件 3.6.0 开始也支持缓存。
仪器化测试执行(即 Espresso 测试)
Android 仪器化测试(DeviceProviderInstrumentTestTask
),通常称为“Espresso”测试,也不可缓存。Google Android 团队也在努力使此类测试可缓存。请参阅此问题。
Lint
Android 的 Lint
任务的用户都知道使用它会带来巨大的性能损失,但也知道它对于查找 Android 项目中的常见问题是不可或缺的。目前,此任务不可缓存。此任务计划在 Android Gradle 插件 3.5 发布时可缓存。这是始终使用最新版本 Android 插件的另一个原因!
Fabric 插件和 Crashlytics
Fabric 插件用于集成 Crashlytics 崩溃报告工具(以及其他工具),非常流行,但在构建过程中会带来一些巨大的性能损失。这是因为您的应用程序的每个版本都需要有一个唯一的标识符,以便在 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")