第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 压缩)的实现类名或输入输出规范,会生成新签名,导致旧版构建缓存失效,进一步影响离线模式下任务执行。
AGP 版本升级导致离线缓存失效的根因路径图 AGP 版本升级 GMM 强制优先级 (元数据模型变更) 全变体感知缓存 (缓存键编码扩展) Transform 签名变化 (缓存失效因子) 缓存键生成失效 离线构建异常 根因传递链: AGP 版本升级 → 三大行为差异(元数据/变体/Transform)→ 缓存键逻辑变更 → 离线缓存大面积失效。

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?可以通过 ./gradlew dependencies --write-locks 检查锁文件变化。
3. 检查你的 Hilt、KSP、Protobuf 版本是否在上文兼容性表的安全区间内。