AGP版本适配模块化CI案例 - 第1节
AGP 简介:你到底在跟谁打交道
做 Android 开发的人,几乎每天都在跟 Gradle 打交道。但说到 AGP(Android Gradle Plugin),我发现很多同学其实分不清「Gradle」和「AGP」的关系。说白了,Gradle 是构建工具本身,而 AGP 是 Google 为 Android 项目写的一个 Gradle 插件。它负责把我们的 Java/Kotlin 代码、资源文件、Manifest 等编译打包成 APK 或 AAB。
我刚开始接触 AGP 时也犯过糊涂——升级了一次 Gradle 版本,结果项目直接崩了,报一堆看不懂的错误。后来才明白,Gradle 和 AGP 有严格的版本对应关系,乱配是要出事的。
AGP 的核心职责
AGP 到底干了哪些事?我列个清单给你看:
- 编译:把 Java/Kotlin 源码编译成 .class 文件
- 打包:把 .class 文件、资源和 AndroidManifest 合并成 APK/AAB
- 签名:用 keystore 对包进行签名
- 混淆:集成 ProGuard/R8 做代码压缩和混淆
- 多维度:支持 flavor、buildType、productFlavor 等构建变体
- 测试:提供单元测试和 Instrumented 测试的任务
简单来说,AGP 就是一个把「你写的代码」变成「用户能安装的应用」的自动化流水线。
版本演进:从 3.0 到 8.x 我都经历了什么
AGP 的版本号很有意思。早期是 1.x、2.x,后来直接跳到了 3.0。我记得从 3.0 开始,AGP 强制要求使用 Gradle 4.x 以上,并且引入了很多新特性。这里我按照自己的经历,把关键版本梳理了一下。
| AGP 版本 | 对应 Gradle 版本 | 核心变化 | 我的印象 |
|---|---|---|---|
| 3.0 - 3.6 | 4.1 - 5.6 | 强制 Java 8 脱糖、引入 implementation/api | 当年从 compile 改到 implementation 那叫一个痛苦 |
| 4.0 - 4.2 | 6.1 - 6.7 | Java 8 脱糖升级、Transform API 变革 | 我开始接触模块化,AGP 4.0 对多模块支持还不错 |
| 7.0 - 7.4 | 7.0 - 7.5 | AGP 独立发布、Android Gradle Plugin 与 Gradle 版本松绑 | 嗯,这个变化让我松了口气,终于不用跟着 Gradle 升了 |
| 8.0 - 8.x | 8.0+ | 非传递性 R 类、默认启用 R8、移除 Transform API | 最新项目已经在用 8.2 了,速度提升很明显 |
重点记住:AGP 每个大版本都有破坏性变更。一定要看官方迁移指南,千万别直接改版本号就编译。
版本号背后的逻辑
为什么 AGP 版本要一直升?其实背后是 Android 平台和构建工具的演进。比如:
- Java 8 语法在 AGP 3.0 开始支持脱糖
- Android 10 的 Scoped Storage 需要新的 API
- 为了支持 App Bundle,AGP 4.0 调整了资源打包逻辑
- 为了缩短构建时间,AGP 8.0 默认启用 R8 并废弃 Transform API
说白了,AGP 的升级往往是被「新特性」和「性能优化」推动的。你不升,就用不了新功能;你升了,就得改代码。这就像追女朋友——不追遗憾,追了累。
AGP 与 Gradle 的版本对应关系
这是最容易踩坑的地方。我见过太多人把 Gradle 7.0 配了 AGP 4.2 然后就报错的。官方有一个兼容性表格,我把它简化一下:
| AGP 版本 | 最低 Gradle 版本 | 建议 Gradle 版本 |
|---|---|---|
| 3.0.x | 4.1 | 4.1 - 4.10 |
| 3.6.x | 5.6 | 5.6 - 6.0 |
| 4.0.x | 6.1 | 6.1 - 6.7 |
| 4.2.x | 6.7.1 | 6.7.1 - 7.0 |
| 7.0.x | 7.0 | 7.0 - 7.4 |
| 8.0.x | 8.0 | 8.0 - 8.4 |
⚠️ 千万不要跨版本升级。比如从 AGP 3.6 直接跳到 7.0,中间有大量 API 废弃,项目大概率起不来。我的建议是:一步一步升,每个大版本至少测一次。
一次迁移踩坑回忆
我曾经把一个老项目从 AGP 3.2 迁移到 AGP 4.2,当时的 Gradle 版本也从 4.6 升到 6.7。我记得改了整整两天。最大的坑有两个:
- Transform API 被废弃:之前用了一个自定义 Transform 做字节码插桩,4.2 虽然还保留但已经 deprecated,到了 7.0 直接移除。我被迫改成了 AsmClassVisitor 方案。
- implementation vs api:以前用 compile 关键词,3.0 改成了 implementation 和 api。我项目里有很多公共库,一不小心就变成了「依赖不可见」,编译不报错,运行就 NoClassDefFoundError。后来花了一整天梳理模块依赖树。
嗯,从那以后我养成了一个习惯:每次升级前先看 release notes,再开一个 git 分支,失败了就切回去。
知识体系总览
下面这张图帮你理清 AGP 在整个构建体系中的位置,以及我们需要关注的核心模块。它不是我临时画的,是多年踩坑总结出来的骨架。
💡 我的习惯:每个新项目开始前,我都会先确定好 AGP 版本和 Gradle 版本。然后写死到 gradle-wrapper.properties 里,同时把 build.gradle 中的 plugin 版本也固定。这样团队其他人拉下来就能跑,不会出现「我电脑能编你不行」的尴尬。
你现在需要知道的
本章我们只做一件事:搞懂 AGP 的「身份」和「身世」。下节课我们会直接进入实战——用 AGP 4.2 创建一个标准的多模块项目,并配置 CI 环境。但如果你对版本对应关系还不清楚,建议把上面的表格多看两眼。我曾经因为版本错配,浪费了一整个下午去排查一个诡异报错,最后发现就是 gradle-wrapper.properties 写错了版本号。
嗯,先消化这些。有时间的话,可以去打开一个老项目看看它的 AGP 版本号,心里有个数。