传统CI架构在AGP升级后面临的问题
AGP 从 7.x 升到 8.x,看似只是版本号跳了一下,但实际跑一遍 CI 你就知道——原来那套分层方式,已经有点扛不住了。
我先说说我的感受。之前在维护一个中等规模的项目,大概二十多个模块,CI 流水线跑了两年多一直挺稳。结果 AGP 升到 8.2 之后,构建时间直接翻倍,缓存也经常失效,搞得团队每天都有人在群里问“今天构建又失败了?”
为什么会这样?说白了,传统 CI 架构在设计时根本没有考虑 AGP 新版的那些“骚操作”——比如配置缓存、资源重定向、非传递性 R 类等等。下面我把几个最突出的问题拆开讲。
问题一:构建速度的瓶颈
AGP 8.x 引入了大量增量构建优化,但前提是你的 CI 必须支持配置缓存和远程缓存。很多团队的 CI 还停留在“全量编译+手动清理”的阶段,升级后构建时间不降反升。
我个人习惯先看构建扫描报告,有一次我发现 assembleDebug 里光是 task execution 就花了 12 分钟,而 AGP 7.x 时同样代码只要 6 分钟。原因很简单:新版的 MergeResources 和 MergeAssets 任务在 CI 环境下频繁全量执行,根本没吃到增量红利。
--no-daemon 或者频繁清理 .gradle 目录,AGP 8.x 的构建缓存几乎等于没用。
问题二:缓存策略的失效
AGP 8.x 对输出产物做了更细粒度的哈希校验。比如 R.java 的生成路径变了,资源 ID 的分配方式也改了。传统 CI 里很多团队直接缓存 build/outputs 目录,升级后缓存命中率极低。
我曾经遇到过一个场景:只是改了一行注释,结果整个 processDebugResources 任务重新执行。查了半天才发现是因为 AGP 8.x 把资源文件的 content hash 也加入到 task 的 inputs 里了。
| 缓存策略 | AGP 7.x 表现 | AGP 8.x 表现 |
|---|---|---|
| 输出目录缓存 | 基本可用 | 命中率下降 60%+ |
| 任务级缓存 | 需要手动开启 | 默认开启但容易误判 |
| 远程缓存 | 可选 | 强烈推荐否则性能倒挂 |
问题三:依赖与插件兼容性
AGP 升级后,很多第三方插件还在吃老版本 API。比如 android-maven-publish、kotlin-android-extensions,甚至一些 lint 插件都会报错。传统 CI 的分层通常把插件配置放在 buildscript 里,升级后很容易出现 classpath 冲突。
我记得有一次,我们只用了一个 com.github.dcendents:android-maven-gradle-plugin,结果 AGP 8.0 后这个插件直接废弃了,CI 构建全部失败。排查了半天才发现是插件内部用了反射访问 AGP 的私有 API。
gradle dependencyInsight --configuration classpath 检查所有插件的 AGP 依赖版本范围。
问题四:资源与类文件重复打包
传统 CI 架构喜欢用 productFlavors + buildTypes 组合出很多变体,然后通过 assemble 任务批量构建。AGP 8.x 在这方面做了严格的资源去重检查,如果两个 flavor 定义了同名但不同内容的资源,CI 会直接报错而不是警告。
我手上有过一个项目,因为 values/strings.xml 里的某个 key 在不同 flavor 里值不一样,但大小写没区分,结果 AGP 8.x 直接中断构建。这在旧版 AGP 下最多一个 warning。
// 传统CI中常见的flavor配置
android {
flavorDimensions "version"
productFlavors {
free {
resValue "string", "app_name", "Free App"
}
paid {
resValue "string", "app_name", "Paid App"
}
}
}
// AGP 8.x 下如果还有重复的resource entry会直接fail
问题五:测试与质量门禁的断层
CI 流水线里通常会包含 test、lint、jacoco 等步骤。AGP 8.x 重构了 Variant API,很多测试框架(比如 Robolectric)需要适配新的变体模型。传统 CI 在做 gradle test 时没有区分 unitTest 和 androidTest 的依赖关系,升级后经常出现 ClassNotFoundException。
我个人习惯是在 AGP 升级后,先单独跑一遍 ./gradlew :app:testDebugUnitTest,看是不是所有测试类都能正常加载。有一次发现 @RunWith(RobolectricTestRunner.class) 报错,原因是 AGP 8.x 移除了旧的 SDK 路径。
总结一下:AGP 升级后,传统 CI 架构在构建速度、缓存、插件、资源、测试五个维度都出现了明显的问题。核心原因是 AGP 8.x 的增量理念和严格校验,与传统 CI 的“全量信任”模式完全不匹配。下一章我会讲如何针对这些问题做分层重构——但在那之前,建议你先对照上面的列表,检查自己团队踩了几个坑。