最近由于项目的编译速度愈来愈慢,严重到有时候甚至接近十分钟才能完成一次完整编译,就决定对着官方文档对Gradle
进行一番优化。优化完成后果真构建速度获得大幅提高,遂在此记录html
因为是对照官方文档并结合实际项目进行优化,因此某些细节或者项目中没有用到的点就简略带过java
Android Studio 和 SDK 工具android
即为生产环境与开发环境分开配置productFlavors
bash
您能够仅为dev
的productFlavors
指定一个语言资源和屏幕密度服务器
productFlavors {
dev {
resConfigs "en", "xxhdpi"
}
...
}
复制代码
通常是在debug时停用网络
android {
...
buildTypes {
debug {
ext.enableCrashlytics = false
}
}
复制代码
始终为进入
manifest
文件的属性使用静态/硬编码值,或者为您的调试构建类型使用资源文件。若是您的manifest
文件或应用资源中的值须要随着每个构建更新,Instant Run
将没法执行代码交换 - 它必须构建和安装新的 APKapp
例如,在您每次想要运行更改时,使用动态版本代码、版本名称、资源或任何其余能够更改
manifest
文件的构建逻辑都须要一个完整的 APK 构建 - 即便实际更改仅须要一个热交换,也是如此。若是您的构建配置须要此类动态属性,那么将其隔离到您的发布构建变体中并让值对您的调试构建保持静态jvm
简单点来讲,就是若是gradle构建中使用了动态构建配置,那么Instant Run
就没法起到应有的做用,与直接构建新的APK没有任何区别模块化
下面是例子
int MILLIS_IN_MINUTE = 1000 * 60
int minutesSinceEpoch = System.currentTimeMillis() / MILLIS_IN_MINUTE
android {
...
defaultConfig {
versionCode 1
versionName "1.0"
...
}
applicationVariants.all { variant ->
if (variant.buildType.name == "release") {
variant.mergedFlavor.versionCode = minutesSinceEpoch;
variant.mergedFlavor.versionName = minutesSinceEpoch + "-" + variant.flavorName;
}
}
}
复制代码
在build.gradle
文件中声明依赖项时,您应当避免在结尾将版本号与加号一块儿使用,例如com.android.tools.build:gradle:2.+
使用动态版本号可能致使意外版本更新和难以解析版本差别,并因 Gradle
检查有无更新而减慢构建速度。您应改成使用静态/硬编码版本号
这个你们都懂,就很少说了
若是您的网络链接速度比较慢,那么在
Gradle
尝试使用网络资源解析依赖项时,您的构建时间可能会延长。您能够指示Gradle
仅使用它已经缓存到本地的工件来避免使用网络资源
这个也是很常见的加快构建速度的方式,尤为是在国内,使用离线模式后构建速度能够大大提高。可是离线模式在每次引用新的依赖时会找不到依赖,因此新项目的话,仍是能不用就不要用吧
为了让 Gradle
准确了解如何构建您的应用,构建系统会在每一个构建前在项目中配置全部模块以及这些模块的依赖项(即便您正在构建和测试一个模块,也是如此)。这会减慢大型多模块项目的构建进程
注意:按需配置在新版的Android Studio中已经没有了
在尝试按需配置的过程当中发现Compile independent modules in parallel
这个选项,查询一番后发现是使用并行化编译,能提升编译速度,勾选便可
在模块化开发中,启用并行化编译提升编译速度更为显著
在应用中查找您能够转换成 Android 库模块的代码。经过这种方式将您的代码模块化可让构建系统仅编译您修改的模块,并缓存这些输出以用于将来构建。这种方式也会让按需配置和并行项目执行更有效(若是您启用这些功能)
就是让你把项目模块化,再也不赘述了
在您建立构建分析后,若是分析显示构建时间中至关大的一部分用在了“配置项目”阶段,请检查 build.gradle 脚本并查找您能够添加到自定义 Gradle 任务中的代码。将某个构建逻辑移动到任务中后,它仅会在须要时运行,能够为后续构建缓存结果,而且该构建逻辑将有资格并行运行(若是您启用并行项目执行)。要了解详情,请阅读官方 Gradle 文档。
就是让你把一些不是必需执行的构建转移到Task中执行,好比某个不须要在Debug时执行的构建
启用这些配置可能加快构建,可是按官网说的,
您应当递增这些设置的值来试验它们并经过分析您的构建观察效果。若是您向进程分配过多的资源,性能可能会降低
因此这个仍是得本身判断是否开启。至于具体的配置对应的含义,官网已经写得很清楚了,就直接发出来
preDexLibraries
声明是否预 dex 库依赖项以加快您的增量构建速度。因为此功能可能减慢您的干净构建的速度,您可能须要为持续性集成服务器停用此功能。maxProcessCount
设置运行 dex-in-process
时要使用的最大线程数量。默认值为 4。javaMaxHeapSize
设置 DEX 编译器的最大堆大小。不过,您应当增长 Gradle
的堆大小(启用 dex-in-process
时,将与 DEX 编译器共享),而不是设置此属性。在项目的 gradle.properties
文件中将 Gradle
的堆大小设置为 2048 MB:
org.gradle.jvmargs = -Xmx2048m
复制代码
这也是老生常谈了,Android Studio里就能直接转换,不过我在项目中并无这么干
若是您没法(或者不想)将 PNG 图像转换成 WebP,仍能够经过在每次构建应用时停用自动图像压缩的方式加快构建速度。要停用此优化,请将如下代码添加到您的 build.gradle
文件中:
android {
...
aaptOptions {
cruncherEnabled false
}
}
复制代码
因为构建类型或产品风味不定义此属性,在构建发布版本的应用时,您须要将此属性手动设置为 true
开启了这个,好像编译速度又能快一个台阶
前面提到过了,前提是脚本中尽可能使用静态依赖。因为目前项目中动态依赖写得太多,因此这个暂时仍是没有用起来
使用 Android 插件 2.3.0 及更高版本的新项目在默认状况下会启用构建缓存(除非您明确停用构建缓存)
使用注解处理器(Annotation-Processing-Tool)时,增量 Java 编译处于停用状态。若是能够,请尝试避免使用注解处理器,以便在不一样构建之间仅编译您修改的类
那么多第三方库用注解写的,通常状况下不太可能停用注解处理
可是不使用Butterknife转而使用findViewById确实能提升编译速度,由于避免了生成对应的注解类。建议在子元素很少或者频繁生成时候直接findViewById
其实就是一篇官网构建速度优化的读后感,但按照提示一步步来,构建速度提高确实比较明显。下一篇会讲讲如何使用构建分析工具来分析构建速度慢的缘由