第1章 AGP版本升级的构建依赖变化全景
1.1 为什么AGP版本升级会破坏离线缓存?
在 Android 构建系统中,离线缓存(--offline 模式、Gradle 构建缓存、预置依赖项)是提升 CI/CD 稳定性和开发效率的关键手段。然而,AGP 版本升级通常会引入依赖解析行为的根本性改变,导致精心搭建的离线缓存体系大面积失效。核心原因在于:AGP 7.x 迁往 8.x 的过程中,Gradle 的依赖元数据解读策略、变体选择逻辑以及构件转换(Artifact Transform)注册机制发生了架构级调整,这些调整直接改变了缓存键(Cache Key)的生成算法,使得旧版缓存命中率急剧下降。
核心认知: AGP 升级不仅仅是 API 表面层的增删改,更会冲击构建系统的“依赖解析引擎”。如果不理解这些底层差异,你将在升级后频繁遭遇「依赖找不到」「缓存未命中」「构建配置错误」等异常。
1.2 AGP 7.x 与 8.x 依赖解析行为差异
下表是 AGP 7.x 与 8.x 在依赖解析域中的关键差异对比,这些差异直接影响离线缓存的行为和命中率:
| 对比维度 | AGP 7.x | AGP 8.x |
|---|---|---|
| 元数据优先级 | POM 优先(多数情况),Gradle Module Metadata (GMM) 可选 | GMM 强制优先,缺乏 GMM 的库可能降级 |
| 变体感知缓存 | 仅区分 runtime / compile 基础变体 |
全变体感知:编码 release、debug、flavor 及能力声明 |
| Artifact Transform | 需明确注册,签名规则宽松 | 隐式启用(如 desugaring、minification),签名编码 transform class 全名 |
| 仓库声明策略 | 允许混合 allprojects 与 dependencyResolutionManagement |
强制统一使用 dependencyResolutionManagement,违规会导致构建异常 |
| 依赖锁定机制 | 支持 gradle.lockfile |
推荐组合 version-catalogs + 锁文件,严格校验版本一致性 |
1.3 离线缓存失效的根本原因分析
针对 AGP 版本升级造成的缓存失效,可以从以下三个技术层面进行根因挖掘:
- Gradle Module Metadata (GMM) 引入: 当库发布者从 POM 切至 GMM 后,Gradle 会优先消费 GMM,不再使用传统 POM。缓存键从
groupId:artifactId:version:classifier变为组:模块:版本:变体:能力列表,这会导致旧版离线包彻底失效。// POM 缓存键(AGP 7.x 常见) com.google.guava:guava:31.1-jre // GMM 缓存键(AGP 8.x 默认) com.google.guava:guava:31.1-jre:runtimeElements:{"require":"com.google.common"} - 变体感知缓存机制: AGP 8.x 强制将构建类型(
buildType)、产品风味(flavor)以及消费者规则文件(如consumerProguardFiles)编码入缓存键。在 AGP 7.x 中,只要依赖坐标不变就可以命中离线缓存;到 8.x 后,相同坐标但不同变体也会产生不同的缓存键,从而按需重新拉取依赖。 - Artifact Transform 签名变化: Transform 的
类全名是缓存键计算的一部分。AGP 升级如果修改了内置 Transform(如 D8 去糖、R8 压缩)的实现类名或输入输出规范,会生成新签名,导致旧版构建缓存失效,进一步影响离线模式下任务执行。
1.4 常用 Gradle 插件版本兼容性参考
离线缓存管理离不开与 AGP 版本相匹配的插件版本。下表是主流插件在 AGP 7.x 和 8.x 中的兼容性对照,错误匹配会直接引起依赖解析失败或缓存异常。
| 插件名称 | AGP 7.4.x | AGP 8.0.x | AGP 8.2.x+ | 关键约束 |
|---|---|---|---|---|
| Kotlin (KGP) | 1.8.x | 1.9.x | 2.0.x | 必须严格对齐 AGP 建议的 KGP 版本,否则元数据解析异常 |
| Hilt | 2.44+ | 2.46+ | 2.50+ | 旧版 Hilt 缺乏对 AGP 8.x 变体感知缓存的支持 |
| KSP | 对应 KGP 1.8.x | 对应 KGP 1.9.x | 对应 KGP 2.0.x | 版本必须与 KGP 完全一致(KSP版本 = KGP版本 + 发布时间戳) |
| Protobuf | 0.9.1 | 0.9.3 | 0.9.4+ | AGP 8.x 中 Lint 集成路径变化,需同步升级 |
| Detekt | 1.22.x | 1.23.x | 1.23.x+ | 对 Gradle 8.x 构建配置 API 的适配要求严格 |
实战要点: 在进行 AGP 版本升级前,应先使用该兼容性表锁定各插件的最低版本。将插件版本放入 Gradle Version Catalog 集中管理,是降低后期离线缓存维护成本的有效手段。
1.5 本章小结
通过本章分析可知,AGP 7.x 到 8.x 的升级绝不仅是一个版本号的变更,它涉及依赖元数据优先级模型、变体感知缓存策略、Artifact Transform 生命周期这三个核心构建子系统的深度重构。离线缓存失效的本质是缓存键生成规则与 Gradle 模块元数据体系的演进产生的代差。
在接下来的章节中,我们将以此为基础,逐步构建一套可以对抗版本升级冲击的离线依赖缓存管理策略,从源头锁定缓存键、显式控制变体解析、并建立自动化兼容性校验系统。
课后自检清单:
1. 你当前的 AGP 版本是 7.x 还是 8.x?是否已经遇到离线缓存失效问题?
2. 你是否在项目中使用了 GMM?可以通过
3. 检查你的 Hilt、KSP、Protobuf 版本是否在上文兼容性表的安全区间内。
1. 你当前的 AGP 版本是 7.x 还是 8.x?是否已经遇到离线缓存失效问题?
2. 你是否在项目中使用了 GMM?可以通过
./gradlew dependencies --write-locks 检查锁文件变化。3. 检查你的 Hilt、KSP、Protobuf 版本是否在上文兼容性表的安全区间内。