第2课:AGP、Kotlin、Gradle的版本匹配
——那些年我们踩过的兼容坑

Gradle 升级翻车,十次里有八次是因为版本不匹配。我说的不是玄学,是实实在在的 NoSuchMethodError 和 UnsupportedOperationException。

AGP(Android Gradle Plugin)、Kotlin 插件、Gradle 本身,这三者就像齿轮。你看上去每个版本都升了,但咬合不对,照样崩。我自己就碰到过一个项目,只升了 Gradle 7.5 没动 AGP,结果构建直接报 Could not get unknown property 'android'。查了半天,原来是 AGP 7.4 不支持 Gradle 8.0+ 的新 API。嗯,从那以后我养成了一个习惯——

升任何组件前,先看官方兼容矩阵。


版本兼容的核心原则

说白了就一句话:大版本号对齐,小版本号宽容。

  • Gradle 主版本号(首位)决定 AGP 的最低要求
  • AGP 主版本号决定 Kotlin 插件的兼容范围
  • Kotlin 插件版本又反过来约束 AGP 的某些特性(比如 Compose 编译器)

我曾经见过一个团队,Kotlin 1.9.0 配了 AGP 8.0,看起来没问题。但他们的 Compose 版本是 1.5.0,而 Kotlin 1.9.0 对应的 Compose 编译器是 1.5.1。结果 Compose 预览全部挂掉,报错说什么内部编译器异常。你想想看,这种错靠看 log 根本猜不到是版本没对齐。

我的铁律:每个季度第一个周一,打开 developer.android.com/build/releases/gradle-plugin,扫一遍兼容表格。


AGP 与 Gradle 的版本对应关系

这是最基础、也最容易出事的。我直接贴一张我自己整理的速查表,你最好保存下来:

AGP 版本 最低 Gradle 版本 推荐 Gradle 版本 备注
7.0.x 7.0 7.0 – 7.3 旧版 R8 兼容问题
7.1.x 7.1 7.1 – 7.4 需升级 JDK 11+
7.2.x 7.2 7.2 – 7.4 AGP 配置缓存问题较多
7.3.x 7.3 7.3 – 7.5 支持 Gradle 配置缓存稳定版
7.4.x 7.5 7.5 – 8.0 ⚠️ 不要用 Gradle 8.0+
8.0.x 8.0 8.0 – 8.2 强制 JDK 17,namespace 必须声明
8.1.x 8.0 8.1 – 8.3 新增短文件名打包
8.2.x 8.2 8.2 – 8.4 NonTransitiveRClasses 默认开启
8.3.x 8.4 8.4 – 8.5 支持 lint 并行分析

避坑技巧:别图新,用 AGP 发布后 3 个月以上的版本。我踩过 8.0.0-alpha 的坑,resource 合并直接炸裂。


Kotlin 插件与 AGP 的版本互动

很多人以为 Kotlin 版本独立于 AGP,其实两者深度耦合。尤其是 IDE 侧,AS 的 Kotlin 插件版本必须匹配 Gradle 里的 Kotlin 版本。否则就会出现「项目编译通过,但 IDE 标红」的灵异现象。

我个人习惯是:Kotlin 版本永远不要领先 AGP 超过一个大版本。举个例子:

  • AGP 7.x 可以用 Kotlin 1.6 ~ 1.8
  • AGP 8.0+ 推荐 Kotlin 1.9+
  • AGP 8.2+ 最好用 Kotlin 1.9.10+(修复了编译器崩溃)

这里有个容易忽略的点:Compose 编译器版本。如果你项目里用了 Compose,Kotlin 版本不能随意升。Compose 编译器是跟着 Kotlin 版本走的。比如:

// build.gradle (app)
android {
    composeOptions {
        kotlinCompilerExtensionVersion = "1.5.1"
    }
}
// 这个版本必须与使用的 Kotlin 版本对应:
// Kotlin 1.9.0  ->  Compose Compiler 1.5.1
// Kotlin 1.9.10 ->  Compose Compiler 1.5.3
// Kotlin 1.9.20 ->  Compose Compiler 1.5.4

我曾经在升级 Kotlin 1.9.20 时,没改 Compose 编译器版本,结果 build 成功但 @Preview 全崩。那个错你根本看不懂——java.lang.InternalError,没有堆栈。最后我硬是被折腾了俩小时才找到根因。

警告:不要在 AGP 版本未稳定时升级 Kotlin 主版本。比如 AGP 8.4 刚出来,匹配的 Kotlin 2.0 还是 RC,直接上必定出IncompatibleClassChangeError。


其他关键依赖的版本约束

除了 AGP 和 Kotlin,还有几个插件也会在升级时反水:

  1. Google Services 插件(com.google.gms:google-services)
    • 4.3.15 只支持 AGP 7.0 ~ 8.1
    • 4.4.0+ 才支持 AGP 8.2+
    • 如果你升了 AGP 8.3 没升 Google Services,build 时直接报 Missing google-services.json —— 其实文件在,只是插件不认。
  2. Firebase Crashlytics 插件
    • 2.9.8 之前与 AGP 8.0 的 namespace 强制声明冲突
    • 我曾经有个客户,升级 AGP 8.2 后 crashlytics 上传签名死活失败,最后发现是插件版本不够。
  3. Hilt / Dagger
    • Hilt 2.44 以下不支持 Gradle 8.0 的配置缓存
    • 如果你的 Gradle 升到 8.2,Hilt 至少得 2.46+,不然 Kapt 会卡死
  4. ButterKnife(别笑,还有人在用)
    • 10.2.3 只支持 AGP 3.x ~ 4.x,到了 AGP 7.0 直接不能用

补个我个人总结的「升级安全清单」:

你要升级 必须一起升级 可能受影响
Gradle 8.0 → 8.4 AGP 8.2+,JDK 17 Hilt、Kapt、AndroidX 构建流程
AGP 7.4 → 8.0 Kotlin 1.8+, Gradle 8.0+, JDK 17 namespace、Crashlytics、Google Services
Kotlin 1.8 → 1.9 Compose Compiler 1.5+, AGP 8.0+ KSP、Jetpack Navigation

版本兼容的全貌图

下面这张图,我画了好久。它把 AGP、Gradle、Kotlin、Compose 编译器、常见插件之间依赖关系串起来了。升级前你看一眼,就知道该动谁、不该动谁。

Gradle 版本兼容关系图 Gradle (主版本号) AGP(Android Gradle 插件) Kotlin 插件 Compose 编译器 Google Services / Crashlytics / Hilt 项目成功构建 ⛔ 常见错误路径 • Gradle 8.0 + AGP 7.4 → 方法找不到错误 • AGP 8.2 + Kotlin 1.7 → IDE 标红但不影响编译 • AGP 8.3 + Google Services 4.3.x → 找不到 google-services.json

实战升级策略(三步走)

看完图,你可能心里有底了。但具体操作我建议你按这个顺序来,少走弯路:

  1. 先确定目标 AGP 版本
    查官方兼容表,确认最低 Gradle 和 JDK 要求。
    然后把 gradle-wrapper.properties 里的 Gradle 版本改过来,别动别的。

  2. 再升级 Kotlin 与 Compose 编译器
    看上面表格,把 Kotlin 版本和 Compose 编译器版本对齐。
    这一步容易遗漏的是 kotlinx.serialization、kotlinx.coroutines 等库,它们也有最低 Kotlin 要求。

  3. 最后处理第三方插件
    按我整理的清单,挨个检查 Google Services、Crashlytics、Hilt 等。
    如果某个插件不支持新 AGP,先升插件,再试 build。不要同时升所有东西。

我的小秘诀:每个步骤做完,跑一次 ./gradlew assembleDebug --dry-run,能快速发现Version mismatch类型错误,不用等完整编译。


常见崩溃与根因速查

我整理了几个我在技术社区里高频看到的问题,你遇到可以直接对照:

错误信息(关键词) 根因 解决方案
Could not find method android() Gradle 版本太高,AGP 太旧 升级 AGP 或降 Gradle
Unsupported class file major version 61 JDK 版本与 AGP 不匹配 升 JDK 到 17 或降 AGP
KotlinJvmAndroidCompilation 报错 Kotlin 插件版本与 AGP 不符 按上面表格调版本
Android resource linking failed AGP 8.0+ 中 namespace 未声明 在 android 块里加 namespace 'com.xxx'
Cannot get property 'android' on null object Google Services 插件版本过旧 升级到 4.4.0+

最后铁律:升级前务必在分支上操作。不要像我那个同事一样,直接改 master 的 build.gradle,然后全组无法编译。他那天下午请全组喝了奶茶才平息众怒。


好了,这一章的核心就是:版本匹配不是玄学,是工程。你只要把上面表格存好,升级前看一眼,大概率不会翻车。下一章我会讲具体崩溃场景 —— 那种 Gradle Sync Failed 弹窗出现时,你该怎么办。

这就是第 2 章的全部内容。我把我知道的、踩过的坑都摊牌了。你如果严格按照这张图和三步走策略来升级,应该不会遇到我当年那种半夜三点还在查 version mismatch 的局面。