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