Android 项目构建速度优化
随着项目的不断扩大,最影响我们的 Code 效率的是项目的编译。下面我就带着大家从 Android 构建流程中去分析如何提高项目的构建效率。
一切从项目编译过程说起
Android 项是从编译到打包流程如下所示:
为了方便大家理解这里对其中主要的构建过程进行描述(上图中绿色椭圆部分):
- aapt:
aapt(Android Asset Packaging Tool)
工具会打包应用中的资源文件,如AndroidManifest.xml、layout
布局中的xml
等,并将 xml 文件编译为二进制形式,当然 assets 文件夹中的文件不会被编译,图片及 raw 文件夹中的资源也会保持原来的形态,(需要注意的是 raw 文件夹中的资源也会生成资源 id。AAPT 编译完成之后会生成R.java 文件
)。 - aidl:AIDL 工具会将所有的 aidl 接口转化为 java 接口。
- Java Compiler(Java编译器):当 AAPT 与 AIDL 工具将需要处理的数据处理好后,Java 编译器会将所有的java代码,包括R.java与 aidl 文件编译成 .class 文件。
- dex:
dex
工具会将上述产生的 .class 文件及第三库及其他 .class 文件编译成 .dex 文件(dex文件是Dalvik虚拟机可以执行的格式),dex文件最终会被打包进APK文件。 - apkbuilder:
apkbuilder
工具会将编译过的资源及未编译过的资源(如图片等)以及 .dex 文件打包成APK文件。 - Jarsingner:生成 APK 文件后,需要对其签名才可安装到设备,平时测试时会使用 debug keystore,当正式发布应用时必须使用 release 版的 keystore 对应用进行签名。Jarsigner工具会根据相应的keystore生成相应的签名APK文件。
- zipalign(release mode):
zipalign
工具,它能够对打包的应用程序进行优化。在你的应用程序上运行zipalign
,使得在运行时 Android 与应用程序间的交互更加有效率。
优化的思路
到了这里有可能有小伙伴会说 “MD,你说了这么说多,那具体优化思路是什么呢?“ 不急,不急,慢慢道来。
从 Android 项目编译的过程中,我们能从几个维度来减少编译的时间:
- 减少不必要的资源编译
- 减少拉取第三方库的时间
- 减少编译时间
- 减少 apbuilder 的打包时间
除了以上维度,还有一个重要的维度,工欲善其事必先利其器。 Android Studio、Android Gradle 插件、 工具的每次更新,都会获得构建方面的优化和新功能。那么从以上几个维度:我们能引入如下的优化方式:
项目实际的改动点
因为时间原因,所以改动点并不是很大,并没有做到类似字节跳动的增量更新方案。但是仍然有着不错的效果。优化前后时间对比如下所示:
全量编译(Rebuild Project) | 增量编译 | 不动任何文件(直接编译) | |
---|---|---|---|
修改前 | 平均 18m | 平均 18-20m | 平均 45s |
修改后 | 平均 8m | 平均 8m | 平均 33s |
整个优化思路如下所示:
- 确保 Android 工具最新
- 使用增量注解处理器
在下面会详细描述整个优化的详细过程。
将 Android Gradle 插件从 3.4.2
升级到 3.6.0
升级到 3.6.0
后具体优势如下所示:
- 并行执行任务
- 新的默认打包工具(在构建应用的调试版本时,该插件会使用一个新的打包工具 zipflinger 来构建 APK。这一新工具应该能够提高构建速度)
- 简化了
R
类的生成过程(Android Gradle 插件通过仅为项目中的每个库模块生成一个 R 类并与其他模块依赖项共享这些 R 类,简化了编译类路径。这项优化应该会加快构建速度)
这里并没有将 Android Gradle 插件升级到最新版本
4.1.0
,是因为在项目中使用的androidannotations
库最大能支持 Android Gradle 插件版本为3.6.0
。
将 androidannotations 注解库升级到 4.7.0
在项目中,我们使用了低版本(4.6.0)的 androidannotations 库来生成中间类。而使用这类的 注解处理器
库会导致一个问题,就是当有新的中间类生成时会引发全量编译。为了提交构建速度,避免全量编译。故将该库升级到最新的 4.7.0 版本。在该版本中该库支持 增量注解处理
androidannotations 4.7.0 最大支持的 Android Gradle 插件版本为
3.6.0
其他改动点
- 移除掉了 fastdex 插件(在实际的项目中并没有使用)
- 移除掉了会在 debug 模式下执行的统计耗时任务(如 findbug,jacoco)
- 修改了部分 atrr.xml 文件及 layout 文件 (因为升级版本造成的编译冲突,所以需要修改)
后续可以做的
- 移除掉无用的库
- 增量 java/kotlin 编译
- transform 优化
- dexBuilder 增量效果量化
- ……
参考资料
最后
站在巨人的肩膀上,才能看的更远~