如何提高Android Studio编译速度

优化后的成果

总体来说效果还是不错的

  1. 全量编译从原来的2-3分钟,优化后再1分钟以内
  2. 增量编译从原来的1分钟,优化后在13s, 甚至更快
优化前的clean后的全量编译时间(2m40s):

优化前的增量编译时间(49s):

代码已经执行

优化后的clean后的全量编译时间(47s):

优化后的增量编译时间(6s):

代码已经执行

优化手段

优化的目的并不是改造原有的编译流程,而是遵循Google的本身的构建流程,方便Google的后续功能优化的升级我们能够快速的相应

耗时点分布

不同App使用的工具不同,也可能存在分化,大体的解决思路是一致的,在遵循Google的原则上,我们需要针对本身App的特性进行优化。保持AS原本的功能不变的原则。

我们可以通过执行命令来分析不同的task的耗时情况

1
2
./gradlew assembleDebug --profile

通过这个可以查看任务的耗时情况,其实AS的build中也能够查看相关的任务耗时信息。

工程耗时原因:

  1. 注解使用,编译时动态生成和插入代码,导致使用的地方每次都会进行代码插入,从而导致进行Multidex 消耗大量时间
  2. 工程中model数据激增,目前有31个model
  3. 优化配置没有进行合理的配置,比如针对本地开发可以简化一些配置

升级Gradle

目前我们gradle 升级到了3.2.1

注解进行增量

Gradle 4.7 已经支持了注解的增量,目前需要注解框架已经在陆续支持增量,所有找到问题,去解决这个并不是难事。

优化配置

目前工程中都是遵循Gradle的本身的编译原则,为了解决本地编译耗时的问题,我们本地编译和线上打包编译是不同的规则,线上打包就是标准的Gradle的流程。本地编译进行了相关的改造

AS本身的配置,把内存使用等各个功能都配置上,比如:

1
2
3
4
5
6
7
8
9
10
# 编译时使用守护进程
org.gradle.daemon=true
#JVM最大允许分配的堆内存,按需分配
org.gradle.jvmargs=-Xmx8192m -XX:MaxPermSize=2048m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
#使用并行编译
org.gradle.parallel=true
org.gradle.configureondemand=true
# 缓存的是javacompiler编译生成的 class,没有cache transform插入的代码,暂时先关闭 cache,后续再研究优化
org.gradle.caching=true

本地编译时,主工程的build.gradle 增加一个api21的Flavors

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
if (isLocalBuild()) {
aaptOptions {
cruncherEnabled = false
}
}

dexOptions {
javaMaxHeapSize "2g"
jumboMode true
incremental true
preDexLibraries true
}

if (isLocalBuild()) {
flavorDimensions "api"
productFlavors {
minApi21 {
minSdkVersion '21'
dimension "api"
}
}
}

本地动态的aar工程

基本思路是,将本地的model全部通过脚本来生成aar供本地编译来使用,减少重复编译aar的时间。工程中只保留一个main工程,不同的业务开发同学在动态生成的配置文件中配置需要开发开启的model

编译

目前将项目工程中只保留了main的代码工程模块,其他的model都以本地Maven的形式存在

首次运行工程

  1. 本地编译默认是采用本地maven仓库的形式,需要执行项目脚本生成 本地arr文件,执行 ./bmaList.sh
  2. 针对自身所在的model进行业务开发,这个需要开启对应的业务开发model,在文件 aar_configs.properties 中的
1
2
open_model_name = framework-base,framework-ui  

填写自身对应的model,注意没有双引号

将model发布成对应的本地maven arr的形式,操作步骤

  1. 首先需要在settings.gradle 中 projectList 中的,移动到 aarList
  2. 在需要发布的model的build.gradle 中添加maven插件
1
apply from: rootProject.getProjectDir().getAbsolutePath() + '/publish.gradle'
  1. 需要在bmaList.sh 中添加,注意添加的顺序,需要在本身model依赖的其他aar对应的model的后面进行添加

单独model的aar发布

项目中提供了单独的model的arr的发布脚本 bma.sh

  1. 执行 ./bma.sh model_name

发布完成后 进行gradle同步

开启所有的model

目前为了方便大家的开发,存在需要开启所有model的情况,这种情况我们进行了简易的支持

在 aar_configs.properties 中配置 open_model_name = –all

然后同步工程

总结

本次的编译速度的优化,是一次尝试。在实际操作过程中,很多同学不习惯去使用,比如开启对应的model,要生成aar等操作相对会繁琐一些。

所以后续我们提供了开启所有的model的配置,尽量做到最大化的适应,对于目前不习惯的同学可以开启所有的model,相应的就是增量编译速度慢一些。

对于熟悉、已经适应的同学可以开启相应的model来开发,提高自己的开发效率。