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。我记得改了整整两天。最大的坑有两个:

  1. Transform API 被废弃:之前用了一个自定义 Transform 做字节码插桩,4.2 虽然还保留但已经 deprecated,到了 7.0 直接移除。我被迫改成了 AsmClassVisitor 方案。
  2. implementation vs api:以前用 compile 关键词,3.0 改成了 implementation 和 api。我项目里有很多公共库,一不小心就变成了「依赖不可见」,编译不报错,运行就 NoClassDefFoundError。后来花了一整天梳理模块依赖树。

嗯,从那以后我养成了一个习惯:每次升级前先看 release notes,再开一个 git 分支,失败了就切回去。

知识体系总览

下面这张图帮你理清 AGP 在整个构建体系中的位置,以及我们需要关注的核心模块。它不是我临时画的,是多年踩坑总结出来的骨架。

AGP 版本适配与模块化 CI 知识体系 Android Gradle Plugin (AGP) 版本适配 AGP ↔ Gradle 对应关系 升级迁移步骤(逐版本升) Transform API & 废弃项 模块化架构 多模块依赖管理 (implementation/api) 构建变体与 productFlavor 非传递性 R 类(AGP 8.0+) CI 实战 Gradle 构建缓存与配置 Jenkins / GitHub Actions 自动打包、签名、发版 📌 本章聚焦:版本适配 + 演进归纳 后续章节会逐步展开 模块化 和 CI 集成的具体实现 但前提是先搞清楚 AGP 是什么、怎么升、怎么配

💡 我的习惯:每个新项目开始前,我都会先确定好 AGP 版本和 Gradle 版本。然后写死到 gradle-wrapper.properties 里,同时把 build.gradle 中的 plugin 版本也固定。这样团队其他人拉下来就能跑,不会出现「我电脑能编你不行」的尴尬。

你现在需要知道的

本章我们只做一件事:搞懂 AGP 的「身份」和「身世」。下节课我们会直接进入实战——用 AGP 4.2 创建一个标准的多模块项目,并配置 CI 环境。但如果你对版本对应关系还不清楚,建议把上面的表格多看两眼。我曾经因为版本错配,浪费了一整个下午去排查一个诡异报错,最后发现就是 gradle-wrapper.properties 写错了版本号。

嗯,先消化这些。有时间的话,可以去打开一个老项目看看它的 AGP 版本号,心里有个数。