加快 Android 项目的 Gradle 构建速度!
介绍
项目构建速度过慢会导致生产力下降,而生产力下降意味着企业蒙受经济损失。本文提供了一系列配置选项和技巧,帮助您加快 Android 项目的 Gradle 构建速度。
免责声明:部分建议包含估算值,这些估算值可能与您项目实际的构建时间改进不完全一致。影响估算值的因素有很多,包括但不限于项目架构、已编写的测试数量、代码检查、当前 Gradle 配置、计算机硬件配置等等。
综上所述,我希望这份清单能够提高你们团队在构建出色应用程序时的整体效率!
缩短项目构建时间
1. 个人资料,个人资料,个人资料!
对构建进行性能分析,数据不会说谎。由于项目架构、测试和代码编写方式可能各不相同,最好始终对自己的构建进行性能分析--profile——最好在每次优化配置更改后都进行分析。您可以在调用 Gradle 任务时直接在命令行中传递参数。
例如,./gradlew assembleDebug --profile。
或者,您也可以在 Android Studio 中运行项目时,将其添加到“首选项”下的命令行选项中。
这是运行该任务后的示例报告--profile。
2. 始终使用最新版本的 Android Gradle 插件
Gradle 团队发布了编译和构建速度更快的 Gradle 新版本。截至撰写本文时,最新版本为 Gradle 5.4.1。
注意,新版本更改可能会引入不必要的编译错误或兼容性问题,升级 Gradle 时请务必查看并遵循迁移指南。

图片来自https://gradle.org/whats-new/gradle-5/
预计这将减少 20-25% 的构建时间。
有关Gradle 5 的更多变化,请点击此处。
3. 避免使用旧版多重索引
多重糖苷酶简介
Android 构建架构存在65,536 个方法引用的限制,即64K 限制。一旦单个Dalvik可执行文件或 DEX 文件达到此限制,就会出现构建错误。Multidex的引入旨在帮助您绕过 64K 限制。
要支持 multidex,只需添加并设置multiDexEnabled为true。
android {
defaultConfig {
...
minSdkVersion 21
targetSdkVersion 28
multiDexEnabled true
}
}
如果您的minSdkVersion设置值低于 20,则必须添加支持库。
android {
defaultConfig {
...
minSdkVersion 15
targetSdkVersion 28
multiDexEnabled true
}
dependencies {
implementation 'com.android.support:multidex:1.0.3'
}
}
但是,此项目设置将使您的构建使用旧版 multidex运行。
传承多重索引
当您启用 multidex 并将 multidex 值minSdkVersion设置为 20 或更低时,就会出现旧版 multidex 问题。在这种情况下,全新构建和增量构建的速度会显著降低。
最简单的解决方法是创建一个用于开发的构建变体。这样,您就可以在测试设备上运行一个隔离的构建变体,而无需担心旧版 multidex 的问题。
android {
defaultConfig {...}
buildTypes {...}
sourceSets {...}
productFlavors {
// Create a separate build variant for development which has a minSdkVersion of 21
dev {
...
minSdkVersion 21
}
prod {...}
}
}
预计这将减少 5-10% 的构建时间。
关于Multidex 的更多信息。
4. 在开发环境中禁用代码检查
注意:恕我直言,我只建议那些电脑配置较低,且在开发过程中对代码检查没有严格要求的团队执行此步骤。
如果代码检查(尤其是对于大型项目)每次构建至少占用 30% 的时间,那就需要重新考虑了。你可能只想在创建差异时运行代码检查,例如运行一个脚本,并将代码检查指定为在创建差异之前要执行的任务之一。
选项 1. 禁用 lint 检查gradle.properties。不建议在CI中运行构建时这样做,因为您可能希望为发布版本启用lint 检查。
gradle=build -x lint
选项 2. 使用 Android Studio 运行项目时,-x lint在“首选项”下传入命令行选项。
选项 3.-x lint在执行 Gradle 任务时通过命令行传递。
例如,./gradlew assembleDebug -x lint。
5. 禁用多 APK 生成
Google Play 商店允许我们为特定设备配置发布多个 APK 文件。splits该模块允许我们配置多 APK 支持。
这是多 APK 支持的示例配置。
android {
splits {
density {
enable true
exclude 'ldpi', 'xxxhdpi'
compatibleScreens 'small', 'xlarge'
}
}
}
但是,我们在开发过程中不需要生成多个 APK 文件。
if (project.hasProperty('devBuild')) {
// Prevent multi apk generation on development
splits.abi.enable = false
splits.density.enable = false
}
Gradle 会针对实例执行项目的构建文件
Project来配置项目。
注意,您需要-PdevBuild在命令中添加内容,以触发带有项目实例属性检查的块。
例如,./gradlew assembleDebug -PdevBuild。
或者,当您使用 Android Studio 运行项目时,请在“首选项”下的命令行选项中传递该参数。
预计这将减少 5-10% 的构建时间。
关于多个 APK 的更多信息。
6. 仅包含最少的资源
避免编译不必要的、未经测试的资源,包括但不限于额外的语言本地化版本和屏幕密度资源。
在开发过程中,您可以通过指定一种语言资源或屏幕密度来优化项目构建时间。
android {
productFlavors {
dev {
...
resConfigs ("en", "xxhdpi")
}
}
}
7. 禁用 PNG 图像处理
无论构建的是发布版本还是调试版本, Android每次构建应用时都会自动执行图像压缩。这有助于优化发布版本中的图像,从而减小应用的大小,但会在开发阶段延长项目构建时间。
更新:自 Android Studio 3.0 Canary 5 版本起即可使用。
PNG 处理功能在发布版本中默认启用,在调试版本中默认禁用。
android {
buildTypes {
release {
// Disables PNG crunching on RELEASE build type
crunchPngs false // Enabled by default for RELEASE build type
}
}
}
对于旧版本的插件
android {
aaptOptions {
cruncherEnabled false
}
}
更多关于crunchPngs的信息。
8. 合理配置 DexOptions
Gradle 提供了一个 DSL 对象,用于配置 dex 选项。其中一个可配置选项是 ` preDexLibrariespre-dex`。您可以选择是否让项目预先编译 dex 库。请注意,这可以提高增量构建的速度,但可能会减慢干净构建的速度。
如果您想启用它,可以这样做。
android {
dexOptions {
preDexLibraries true
}
}
请根据您的开发工作流程偏好进行合理配置。在持续集成 (CI) 构建中执行全新构建时,应禁用此功能。
9. 仅在需要时使用 Crashlytics
每次构建时,Crashlytics都会生成唯一的构建 ID。禁用 Crashlytics 插件可以加快调试构建速度。
android {
buildTypes {
debug {
ext.enableCrashlytics = false
}
}
}
接下来,在初始化调试版本时,在运行时禁用该工具包。
val crashlytics = Crashlytics.Builder()
.core(CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build())
.build()
Fabric.with(this, crashlytics)
但是,如果您需要在调试版本中使用 Crashlytics,您仍然可以通过阻止它在每次构建时使用其自身唯一的构建 ID 更新应用程序资源来改进增量构建。
android {
buildTypes {
debug {
ext.alwaysUpdateBuildId = false
}
}
}
关于Crashlytics 构建工具的更多信息。
10. 使用静态依赖版本
您必须在配置文件中为依赖项声明静态或硬编码的版本号build.gradle。应避免使用动态依赖项(用加号 (+) 表示),否则可能会遇到意外的版本更新。动态依赖项声明还会降低构建速度,因为它会持续在线检查更新。
android {
dependencies {
// What you should not do
// implementation "androidx.paging:paging-runtime:2.+"
// What you should do
implementation "androidx.paging:paging-runtime:2.1.0"
}
}
11. 启用构建缓存
默认情况下,构建缓存未启用--build-cache。要使用构建缓存,可以在执行 Gradle 任务时通过命令行参数调用它。
例如,./gradlew assembleDebug --build-cache。
您还可以配置gradle.properties文件的构建缓存。
org.gradle.caching=true // Add this line to enable build cache
预计这将使您的完整全新构建速度提高 3 倍,增量构建速度提高 10 倍!
12. 配置 JVM 的堆大小
Gradle 守护进程现在启动时使用 512MB 的堆内存,而不是 1GB。默认情况下,此配置可能最适合小型项目。但如果您有一个大型项目,则应通过org.gradle.jvmargs在文件中设置属性来更新堆内存大小gradle.properties。
这是默认配置。
org.gradle.jvmargs=-Xmx512m "-XX:MaxMetaspaceSize=256m"
如果要将堆大小更新为 2GB 以用于更大的项目。
org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
file.encoding此外,您还需要在 JVM 执行 Gradle 构建时(例如,Gradle Daemon 启动时)设置正确的属性。在本例中,我们将其设置为 UTF-8。
关于Gradle 默认内存设置的更多信息。
13. 将你的项目模块化
将项目代码库模块化,可以让 Gradle 构建系统只编译你修改过的模块,并将这些输出缓存起来以供将来构建使用。
以下是项目模块化的简要概述。
构建系统如何根据模块特定的更改编译您的项目。
我推荐模块化,不仅因为模块可以重用,可以优化构建时间,还因为它能够支持最新的Android 动态功能和即时应用。
以下是Joe Birch 撰写的关于 Android 应用程序模块化的文章。
本文由 Nikita Koslov 撰写,详细介绍了模块化如何提高 Android 应用的构建速度。
14. 亚军:始终开启的守护进程、并行构建执行和按需配置。
Gradle守护进程
默认情况下,Gradle Daemon 已启用,但如果您当前管理的项目在每次构建时都禁用了该守护程序,并且这让您感到烦恼,则您可能需要通过启用它来更新配置。
org.gradle.daemon=true
并行构建执行
这种配置仅在您的项目采用模块化设计时才有效。它可以让您充分利用计算机的处理资源。
org.gradle.parallel=true
关于并行执行的更多信息。
按需配置
只有当您拥有多个项目且这些项目彼此解耦时,这种配置才能带来好处——请注意,是多项目,而不仅仅是模块化项目。
让我们以 Google I/O 2018 Android 应用为例。
请注意项目结构,它包含各种项目,例如mobile、 和tv。按需配置将尝试仅配置与请求的任务相关的项目(例如,仅为请求的任务进行配置)。 mobile
注意:按需配置功能尚处于测试阶段,因此不能保证每次构建都能正常工作。
更多关于按需配置的信息。
结论
确保你的团队及时了解最新的 Gradle 版本,并留意可能出现的 API 弃用情况。始终对构建过程进行性能分析,并根据分析结果相应地调整配置。
希望这些建议能显著提高你们团队的生产力,并帮助彼此再次开发出优秀的应用程序!
如果您有任何问题或建议,请随时在下方评论或在我的推特账号@devjdg上提问。
祝您编程愉快!
文章来源:https://dev.to/joshuamdeguzman/speed-up-your-android-project-s-gradle-builds-1366






