Gradle 8.x 新特性:配置缓存稳定版、Kotlin DSL 成为默认、Version Catalog 正式版、AGP 8.0 兼容性、移除 Transform API

说实话,Gradle 8.x 的发布,是我这几年见过的最「硬核」的一次升级。它不像以前那样小修小补,而是直接动了几条核心命脉。我刚开始升级项目时,心里也犯嘀咕——这玩意儿会不会又把我的构建搞崩?但用下来发现,只要理解了它的设计意图,这其实是一次非常值得拥抱的进化。

咱们一个一个来看。

配置缓存:终于从「实验」走向「稳定」

配置缓存(Configuration Cache)这个概念,最早在 Gradle 6.6 就以实验特性出现了。说白了,它的目标就是:让增量构建快得像闪电

你想想看,以前每次跑 Gradle 任务,它都要重新解析所有 build.gradle 脚本,重新配置所有 Task。哪怕你只改了一行代码,它也得把整个构建逻辑「演」一遍。这就像你每次进厨房,都得重新设计一遍菜谱——太傻了。

配置缓存的做法是:把构建配置的结果序列化下来。下次构建时,如果输入没变,直接反序列化恢复配置,跳过脚本解析和 Task 注册阶段。

我在项目中遇到过最夸张的情况:一个大型模块化项目,冷构建配置阶段要跑 40 秒。开启配置缓存后,第二次构建直接降到 5 秒以内。那种感觉,就像从绿皮火车换成了高铁。

启用方式:在 gradle.properties 中设置

org.gradle.configuration-cache=true

或者直接在命令行加参数:

./gradlew assembleDebug --configuration-cache

注意:配置缓存对 Task 的输入/输出声明要求非常严格。如果你的 Task 使用了非序列化的对象,或者依赖了外部状态(比如系统属性、环境变量),可能会触发缓存失效甚至报错。我曾经因为一个自定义 Task 里用了 System.currentTimeMillis() 做文件名,结果缓存永远不命中——嗯,这坑我替你们踩过了。

Kotlin DSL:不再是「二等公民」

从 Gradle 8.0 开始,Kotlin DSL 正式成为默认的构建脚本语言。这意味着什么?意味着你新建项目时,生成的 build.gradle.kts 就是默认配置了。

我个人习惯用 Kotlin DSL 已经两年了。说实话,刚开始确实有点不适应——毕竟 Groovy 那种「无类型、随便写」的风格用久了,突然被 Kotlin 的类型安全约束住,会觉得束手束脚。但用久了你会发现,类型安全带来的好处远超想象

举个例子:

// Groovy 写法
android {
    compileSdkVersion 33
    defaultConfig {
        minSdkVersion 21
    }
}

// Kotlin DSL 写法
android {
    compileSdk = 33
    defaultConfig {
        minSdk = 21
    }
}

你看,Kotlin DSL 里用的是 compileSdk 而不是 compileSdkVersion。IDE 会自动补全,写错了直接标红。Groovy 里写错了,只能等到运行时崩溃才发现。

迁移建议:如果你还在用 Groovy,不用急着一次性全改。Gradle 8.x 依然兼容 Groovy 脚本。我建议你从新模块开始用 Kotlin DSL,慢慢过渡。或者用 .gradle.kts.gradle 混用——Gradle 是支持的。

Version Catalog:依赖管理的「中央厨房」

Version Catalog 在 Gradle 7.0 时还是实验特性,到了 8.x 终于转正了。它的核心思想很简单:把所有的依赖版本号集中管理,而不是散落在各个模块的 build.gradle 里。

我以前维护过一个 20+ 模块的项目,每个模块都写着 implementation 'com.squareup.okhttp3:okhttp:4.9.3'。后来要升级 OkHttp,我得全局搜索替换——漏一个就等着编译报错吧。

用了 Version Catalog 之后,事情变成了这样:

gradle/libs.versions.toml 中定义:

[versions]
okhttp = "4.9.3"
retrofit = "2.9.0"

[libraries]
okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }

然后在模块中引用:

dependencies {
    implementation(libs.okhttp)
    implementation(libs.retrofit)
}

升级版本时,只需要改 libs.versions.toml 这一个文件。所有模块自动同步。爽不爽?

注意:Version Catalog 还支持 bundles(依赖组)和 plugins(插件版本管理)。比如你可以把「测试相关依赖」打包成一个 bundle,然后在模块里一行引入:

testImplementation(libs.bundles.testing)

AGP 8.0 兼容性:该来的总会来

AGP 8.0 和 Gradle 8.x 是深度绑定的。如果你要升级到 Gradle 8.x,AGP 也必须跟着升级到 8.0 以上。这中间有几个关键变化:

  • 最低 Gradle 版本要求提升:AGP 8.0 要求 Gradle 8.0+,AGP 8.1 要求 Gradle 8.1+,以此类推。
  • Java 11 成为最低要求:AGP 8.0 不再支持 Java 8。你的 JDK 必须升级到 11 或更高。
  • R8 全面替代 ProGuard:AGP 8.0 移除了对 ProGuard 的支持,全面转向 R8。如果你还在用 ProGuard 的某些特性,需要检查是否兼容。

我在升级时遇到过一个坑:项目里用了 android.enableR8=false 来禁用 R8。AGP 8.0 直接报错,说这个属性已经移除了。没办法,只能硬着头皮迁移到 R8。好在 R8 的兼容性已经很好了,大部分 ProGuard 规则都能直接使用。

Transform API 移除:告别「旧时代」

这个变化,对插件开发者来说影响最大。Transform API 从 AGP 1.5 就开始存在了,很多第三方插件(比如某些字节码插桩工具)都依赖它。但它的设计有缺陷:性能差、难以增量构建、与配置缓存不兼容

AGP 8.0 正式移除了 Transform API,取而代之的是 AsmClassVisitorFactoryInstrumentation API

如果你维护过自定义 Transform,应该知道那种痛苦:每次构建都要遍历所有 class 文件,哪怕只改了一个类。新的 API 支持增量处理,只处理变化的文件,性能提升非常明显。

迁移提醒:如果你项目里用了依赖 Transform API 的第三方插件(比如某些热修复、埋点插件),一定要确认它们是否已经适配了 AGP 8.0。否则升级后直接编译失败。我曾经因为一个老旧的字节码插件没适配,卡了整整两天才找到替代方案。

知识体系总览

下面这张图,帮你快速理清 Gradle 8.x 这五大变化的关系:

Gradle 8.x 五大核心变化 Gradle 8.x 配置缓存 增量构建加速 Kotlin DSL 默认构建脚本语言 Version Catalog 依赖版本集中管理 AGP 8.0 兼容 JDK 11 / R8 强制 Transform API 已移除,改用新API 核心目标:更快的构建速度 + 更安全的依赖管理 + 更现代的 API

这五个变化,其实都指向同一个目标:让 Android 构建更快、更稳、更可维护。配置缓存和 Transform API 的移除,解决的是性能问题;Kotlin DSL 和 Version Catalog,解决的是可维护性问题;AGP 8.0 的兼容性要求,则是推动整个生态向前走。

我个人建议,如果你还在用 Gradle 7.x 甚至更老的版本,现在就可以开始规划升级了。虽然迁移过程可能会遇到一些小坑,但长远来看,这些新特性带来的收益绝对值得你投入时间。

嗯,这一章的内容就到这里。下一章我们会深入探讨如何自定义 Gradle 插件,到时候我会分享一些我在实际项目中写插件的经验和踩过的坑。


公众号:蓝海资料掘金营,微信 deep3321