接手一个几年历史的老项目,打开 build.gradle,映入眼帘的往往是臃肿的 buildscript 块、散落各处的 ext { ... } 变量,以及各个子模块里相互打架的版本号。

如果你想让项目焕然一新,接入 Gradle 官方推荐的 Version Catalog (TOML) 是必经之路。别怕,迁移过程其实非常有规律可循,只需按照以下 4 个步骤操作即可。

阶段一:建立“中央物资室”

不要一上来就去删老代码!我们要先建好新的大本营。

操作: 在项目根目录下的 gradle/ 文件夹中,新建一个文件,命名为 libs.versions.toml。 并填入基础骨架:

Ini, TOML

[versions]
# 这里放所有的版本号数字

[libraries]
# 这里放所有的依赖库 (Jar/AAR)

[plugins]
# 这里放所有的 Gradle 插件

阶段二:迁移插件(Plugins)—— 从 Classpath 到 Alias

这是最核心、也是最容易出错的一步。我们要把老式的 classpath 引入,替换为现代的 alias 引入。

1. 提取到 TOML 中

【改造前】根目录 build.gradle

Gradle

buildscript {
    ext.agp_version = '8.0.0'
    ext.kotlin_version = '1.8.20'
    dependencies {
        classpath "com.android.tools.build:gradle:$agp_version"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

【改造后】在 libs.versions.toml 中添加:

Ini, TOML

[versions]
agp = "8.0.0"
kotlin = "1.8.20"

[plugins]
# 注意:插件的 ID 是固定的,通常可以在老项目的子模块 apply plugin 里找到
android-application = { id = "com.android.application", version.ref = "agp" }
android-library = { id = "com.android.library", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }

2. 重构根目录 build.gradle

【改造前】:根目录可能只有 buildscript 块。 【改造后】:删除 buildscriptdependencies 块,换成 plugins 块,并加上我们之前讲过的 apply false

Gradle

// 根目录 build.gradle
plugins {
    alias(libs.plugins.android.application) apply false
    alias(libs.plugins.android.library) apply false
    alias(libs.plugins.kotlin.android) apply false
}

3. 重构子模块 build.gradle

【改造前】

Gradle

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'

【改造后】

Gradle

plugins {
    alias(libs.plugins.android.application)
    alias(libs.plugins.kotlin.android)
}

阶段三:迁移依赖库(Libraries)

插件搞定了,接下来是日常用得最多的依赖库(比如 Retrofit, Glide, Gson 等)。

1. 提取到 TOML 中

【改造前】子模块的 dependencies

Gradle

dependencies {
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
}

【改造后】在 libs.versions.toml 中添加:

Ini, TOML

[versions]
retrofit = "2.9.0"

[libraries]
# 拆分逻辑:group:name:version
retrofit-core = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" }
retrofit-gson = { group = "com.squareup.retrofit2", name = "converter-gson", version.ref = "retrofit" }

2. 重构子模块依赖

回到子模块的 build.gradle,享受代码补全的快感吧! 【改造后】

Gradle

dependencies {
    implementation(libs.retrofit.core)
    implementation(libs.retrofit.gson)
}

阶段四:大扫除(Cleanup)

当所有的子模块都迁移完毕,并且点击 Sync Project with Gradle Files 成功通过后,你就可以放心大胆地执行最后一步了:

  1. 删掉根目录所有的 ext { ... } 闭包

  2. 删掉根目录的 buildscript { dependencies { ... } }(注意:buildscript { repositories { ... } } 如果有私有仓库,需要迁移到 settings.gradlepluginManagement 中,或者暂时保留仓库声明)。

  3. 拥抱你干干净净的、纯声明式的现代化 Gradle 脚本!


避坑小贴士 💡

  1. 命名转换规则:如果你在 TOML 里用中划线命名了 retrofit-core,在 build.gradle 中调用时,Gradle 会自动将中划线变成点:libs.retrofit.core

  2. 渐进式迁移:不需要一天之内改完。老写法和 TOML 写法是可以共存的。你可以先迁移插件,明天再迁移网络库,后天再迁移 UI 库。