背景:AGP 升级为何影响构建速度
AGP 升级后构建变慢,这几乎是每个 Android 团队都会遇到的痛。我记得 2022 年初,我带团队把一个项目从 AGP 4.2 升级到 7.2,全量构建时间直接从 4 分钟飙到了 11 分钟。当时团队差点就要回退版本了。
为什么会这样?说白了,AGP 的每次大版本升级,背后都是 Gradle API、Task 图、编译策略和缓存机制的一系列调整。任何一个环节出问题,都会拖慢构建速度。
1.1 从现象说起:升级后构建变慢了
先看一组我实际测过的数据。同一个项目,只升级 AGP 版本,其他配置不变:
| AGP 版本 | 全量构建耗时 | 增量构建耗时 | 缓存命中率 |
|---|---|---|---|
| 4.2.2 | 4min 12s | 38s | 87% |
| 7.0.4 | 7min 48s | 1min 52s | 62% |
| 8.0.2 | 11min 03s | 2min 41s | 45% |
增量构建时间翻了 4 倍多,缓存命中率接近腰斩。你想想看,这对开发效率的影响有多大。团队每天要跑几十次构建,每次多等几分钟,积少成多就是半天的工作量。
想快速定位问题,第一步就是跑一次构建扫描:
./gradlew assembleDebug --build-cache --scan
这个命令会生成一份详细的构建报告,后面几章我们会反复用到它。
1.2 根因一:Gradle API 的断层式变更
AGP 升级后,Gradle API 经常出现不兼容。我遇到过最典型的问题,是 AGP 7.0 开始强制要求使用 Gradle 7.x 系列,而很多第三方插件还没跟上。
举个例子,一个自定义 Transform Task 在 AGP 4.x 下跑得好好的,升级到 7.x 后直接罢工。因为 AGP 7.0 废弃了 Transform API,改用 AsmClassVisitorFactory。不迁移的话,构建就会卡在某个 Task 上过不去。
迁移前后的代码对比大概是这样:
// AGP 4.x 方式(已废弃)
class MyTransform : Transform() {
override fun transform(...) {
// 处理字节码
}
}
// AGP 7.x+ 方式
class MyVisitorFactory : AsmClassVisitorFactory<MyParameters> {
override fun createClassVisitor(...): ClassVisitor {
return MyClassVisitor(...)
}
}
避坑指南:我曾经在一个项目里,因为内部插件用了 Transform API,升级后构建直接挂掉。花了整整两天才把所有 Transform 迁移完。建议你在升级前先用 --scan 跑一遍,看看有没有废弃 API 的警告。
1.3 根因二:Task 依赖图被重构
AGP 每次升级,Task 图都会发生变化。说白了就是 Gradle 在执行构建时,各个 Task 之间的依赖关系被重新组织了。
我记得从 AGP 4.2 升级到 7.0 时,最大的感受是 mergeDex 和 package 相关的 Task 被拆分成了多个子 Task。表面上 Task 变多了,但单个 Task 的执行时间反而更难优化了。
Task 图重构带来的直接影响有两个:
- 增量构建失效——Task 的输入输出配置变了,Gradle 会认为之前的缓存无效,被迫全量重跑。
- 并行度下降——Task 依赖关系变复杂,能并行执行的 Task 变少了,CPU 利用率上不去。
举个例子,AGP 7.x 中新增了 extractProguardFiles 和 mergeExtDex 等 Task,它们的依赖链条比旧版本长了不少。我在项目中用 --dry-run 对比过,Task 总数从 180 个增加到了 260 个左右。
1.4 根因三:编译与缓存策略的调整
AGP 升级后,编译策略也会变。比如 AGP 7.0 开始默认启用 R8 全量混淆,而之前是 ProGuard + R8 混合模式。R8 的处理逻辑更重,自然拖慢构建时间。
另外,Gradle 的构建缓存机制也在变。AGP 7.0 引入了新的缓存键计算方式,同一个代码分支在不同机器上构建,缓存可能不命中。我之前就踩过这个坑——CI 机器和本地开发机的构建缓存一直对不上,白白浪费了半小时去排查。
--build-cache 参数配合 --scan 来分析缓存情况。如果命中率低于 60%,说明缓存策略出了问题,需要重点排查。
1.5 一张图看懂 AGP 升级影响链路
下面这张图总结了 AGP 升级影响构建速度的核心链路。从版本升级出发,经过四个关键因素的传导,最终导致构建性能下降:
从这张图可以看出,AGP 升级不是单一原因导致构建变慢,而是多个因素叠加后的结果。我在实际项目中见过最典型的场景是:API 断层 + 缓存失效 + Task 图重构三者同时发生,构建时间直接翻倍。
了解这些根因之后,下一步就是用网络瀑布图把每个环节的耗时拆解出来。这也是后面几章要讲的重点——怎么用工具定位具体是哪个 Task 卡住了构建。