缓存 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 插件
Android Studio 用户应使用最新的 Android 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
}
单元测试执行
与纯 Java 项目中的单元测试类似,Android 项目中等效的测试任务 (AndroidUnitTest
) 自 Android Gradle Plugin 3.6.0 起也是可缓存的。
Instrumentation 测试执行(即 Espresso 测试)
Android instrumentation 测试 (DeviceProviderInstrumentTestTask
),通常称为“Espresso”测试,也是不可缓存的。Google Android 团队也在努力使此类测试可缓存。请参阅 此问题。
Lint
Android Lint
任务的用户非常清楚他们为使用它而付出的巨大性能代价,但也知道它对于查找 Android 项目中的常见问题是不可或缺的。目前,此任务不可缓存。此任务计划在 Android Gradle Plugin 3.5 版本中实现可缓存。这是始终使用最新版本 Android 插件的另一个原因!
Fabric 插件和 Crashlytics
Fabric 插件用于集成 Crashlytics 崩溃报告工具(以及其他工具),非常受欢迎,但在构建过程中会带来一些沉重的性能损失。这是因为您的应用程序的每个版本都需要一个唯一的标识符,以便可以在 Crashlytics 仪表板中识别它。实际上,Crashlytics 的默认行为是将“每个版本”视为与“每次构建”同义。这破坏了 增量构建,因为每次构建都是唯一的。这也破坏了构建中某些任务的可缓存性,原因相同。只需在“debug”构建中禁用 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")