升级前评估:当前项目使用的 Gradle 版本归纳总结

升级 Gradle 最怕什么?最怕一拍脑袋就改版本号,然后整个项目崩给你看。我经历过太多次这样的“惊喜”——明明只是改了个小版本,结果编译时报出一堆看不懂的异常,调试两天才发现是某个插件的兼容性问题。所以,升级前先摸清家底,这件事比写代码本身还重要。

为什么要做版本评估?

说白了,Gradle 本身和它的插件、构建脚本、甚至 JDK 版本之间都存在微妙的依赖关系。你想想看,升级一个构建工具,影响的可是整个构建管道。我不止一次在项目里看到:gradle-wrapper.properties 里写了 7.4,但 build.gradle 里却用了只在 6.x 上稳定的插件语法,结果一跑就报错。这种事很常见。

所以我的习惯是:在动手升级前,先画一张“版本关系图”。把当前项目里所有跟 Gradle 版本相关的要素列清楚,然后逐一评估升级带来的影响。下面这个流程就是我平时用的方法:

升级前评估流程 ① 确定升级诉求 ② 收集 Gradle 版本信息 ③ 分析依赖兼容性 ④ 检查插件版本匹配 ⑤ 制作兼容性矩阵 ⑥ 决策升级路径 评估不是一次性的 每次大版本升级都应 从头梳理一遍 常见坑:只看 Gradle 版本 忽略了 AGP、Kotlin 插件 JDK 版本的联动变化

第一步:翻查 Gradle Wrapper

项目里最直接的版本信息藏在 gradle/wrapper/gradle-wrapper.properties 里。打开它,找到 distributionUrl 这一行:

distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip

这里的 7.4.2 就是当前项目正在使用的 Gradle 发行版。但注意,这仅仅是“Wrapper 指定的版本”。实际运行时还可能被本地安装的 Gradle 覆盖?我个人习惯在终端里跑一句 ./gradlew --version 来确认真正生效的版本:

$ ./gradlew --version
------------------------------------------------------------
Gradle 7.4.2
------------------------------------------------------------
Build time:   2022-03-31 15:36:47 UTC
Revision:     d5ad7e120eb1ef2dc4b4b5ff1c08b5f0f7a7f7f7
Kotlin:       1.5.31
Groovy:       3.0.9
Ant:          Apache Ant 1.10.11
JVM:          11.0.15 (Oracle Corporation 11.0.15+10)
OS:           Mac OS X 11.6

输出里最关键的几个信息:Gradle 版本、Kotlin 版本、JVM 版本。这三个东西往往需要一起升级。

提示:如果团队多人协作,务必确保所有人的 gradle-wrapper.properties 一致。我曾经见过因为某位同事本地手动改了版本号没提交,导致 CI 和本地构建结果不一致,排查了整整一个下午。

第二步:盘点项目中的插件和依赖

Gradle 自身升级后,影响最大的是生态中的插件——尤其是 Android Gradle Plugin (AGP)、Kotlin 插件、以及各种第三方构建插件。我一般会列一张表,记录当前每个核心插件的版本:

插件名称 当前版本 目标 Gradle 版本兼容范围 备注
com.android.application7.2.1Gradle 7.0+建议一同升级到 AGP 7.4+
org.jetbrains.kotlin.android1.6.21Gradle 7.0+ (Kotlin 1.6 需 JDK11+)Kotlin 1.8 开始要求 Gradle 7.6+
com.google.dagger.hilt.android2.44Gradle 7.0+Hilt 2.44 兼容性较好
io.realm10.11.1Gradle 7.3+Realm 对 Gradle 版本较敏感

你看,每个插件都有自己要求的 Gradle 最低/最高版本。如果直接升级 Gradle 到 8.0,可能某个插件还没适配,就需要同时升级插件或者找替代方案。我记得有一次在升级到 Gradle 7.6 时,项目里用的一个古老版本的 Kotlin 插件报错说“不支持的 Gradle API”,最后不得不连升三个版本的 Kotlin 才解决。

第三步:检查构建脚本语法变更

Gradle 每个大版本都会废弃或移除一些 API。我习惯在升级前先看看 Gradle 官方 Release Notes 中的“Deprecations”部分。比如从 7.x 升级到 8.x,最明显的变化就是:

  • compile、runtime 配置名称被彻底移除(已在 7.x 废弃)
  • Project 的 buildscript() 闭包行为有调整
  • 某些 Gradle API 在 8.x 中被标记为 @Internal,自定义 Task 需要适配

另外,别忘了看看 settings.gradle 里有没有使用 pluginManagement、dependencyResolutionManagement 这些新语法。我在一个老项目里发现 settings.gradle 还用的旧式 apply plugin 方式,升级 Gradle 后直接编译失败。

警告:升级 Gradle 之前,最好先把项目备份到 Git 分支,并确保本地有一个干净的构建缓存(./gradlew clean)。我曾经掉过一个坑:升级后直接跑 ./gradlew build,结果因为缓存了旧的 Gradle 版本编译产物,报了一堆诡异的链接错误。清掉 .gradle/caches 再重新构建才解决。

制作版本兼容性矩阵

把所有信息收集完之后,我通常会用一张矩阵图来可视化“当前版本 → 目标版本”的升级路径。下面是一个简化的例子:

组件 当前版本 目标版本(Gradle 8.2) 需要同步升级?
Gradle7.4.28.2—
AGP7.2.18.1.0是(AGP 8.x 配合 Gradle 8.x)
Kotlin1.6.211.9.0是(1.6 不支持 Gradle 8.x)
JDK1117建议升级(Gradle 8.x 推荐 JDK17)
Hilt2.442.48是

这张表做出来之后,你就可以按图索骥,逐项升级。注意,升级顺序也有讲究——我一般先升级 JDK,再升级 Gradle,接着升级 AGP/Kotlin,最后升级其他第三方插件,每升级一项就构建一次,确保不会一次性积累太多问题。

避坑指南:我踩过的那些雷

这部分全是真金白银的经验,你看完也许能省下半天调试时间:

  • 不要跳过小版本。 我曾尝试从 Gradle 7.2 直接跳到 8.0,结果 AGP 7.2 根本不支持,连报错信息都不友好。建议至少先升级到 7.6 过渡一下。
  • 检查 Gradle Daemon 状态。 有时升级后旧 Daemon 还在运行,导致新版本没生效。执行 ./gradlew --stop 重启 Daemon 再试。
  • 关注 Gradle 插件发布的 compatibility matrix。 比如 AGP 8.x 明确要求 Gradle 8.x,但有些三方插件(比如 Realm、Dagger Hilt)可能还停在试验性支持阶段。
  • 配置中的 compileSdk 和 targetSdk 也可能需要同步调整。 这不是 Gradle 直接管的事,但升级 AGP 后编译行为会变,比如默认启用了 R8 混淆规则的新格式。
核心原则:升级前评估不是为了完美预测,而是为了把风险控制在可接受的范围内。你花在评估上的时间,通常可以为你避免 3-5 倍的排错时间。