libs.versions.toml 必须置于 gradle/libs.versions.toml,编码为 UTF-8 无 BOM,需在 settings 中启用 VERSION_CATALOGS 预览;版本、依赖、插件须分三段定义,引用时插件用 alias()、依赖用 libs.xxx,命名推荐短横线格式。

libs.versions.toml 文件必须放在 gradle/libs.versions.toml
Gradle 只在固定路径识别 version catalog:项目根目录下的 gradle/libs.versions.toml,路径写错或文件名带后缀(如 .toml.bak)都会导致 libs 不可用,IDE 也不会补全。Android Studio 2023.3+ 对该路径有专属高亮和校验支持,但前提是文件存在且未被 IDE 忽略(比如被 .gitignore 误删了)。
常见错误现象:Unresolved reference: libs 或 Cannot resolve symbol 'libs',90% 是因为文件位置不对、拼写错误(比如写成 lib.versions.toml),或者没启用 preview 功能。
- 确保
settings.gradle.kts或settings.gradle顶部有enableFeaturePreview("VERSION_CATALOGS") - 不要在
build.gradle中手动apply from:引入 TOML;它由 Gradle 自动加载 - TOML 文件编码必须是 UTF-8,BOM 头会导致解析失败(尤其 Windows 下用记事本保存时容易带 BOM)
版本、依赖、插件三类定义要分清 [versions] / [libraries] / [plugins]
[versions] 只存纯版本号字符串,不带引号也不带逻辑;[libraries] 定义具体依赖坐标,必须用 version.ref 指向 [versions] 里的 key;[plugins] 同理,但只接受 id + version.ref 形式。
容易踩的坑:
- 把版本直接写死在
[libraries]里,比如version = "1.2.3"—— 这会绕过 catalog 机制,失去统一升级能力 - 在
[libraries]中混用module和group/name:前者适合 Maven BOM 或扁平化坐标(如"com.squareup.okhttp3:okhttp"),后者更利于 IDE 补全和类型安全,推荐优先用group+name -
[plugins]里写apply = true—— catalog 不负责应用插件,只提供声明;实际应用仍需在plugins { }块中用alias(libs.plugins.xxx)
示例正确写法:
[versions]
kotlin = "1.9.20"
androidx-core = "1.12.0"
[libraries]
kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib", version.ref = "kotlin" }
core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "androidx-core" }
[plugins]
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
在 build.gradle.kts 中引用时必须用 alias() 或 libs.xxx
插件要用 alias(),依赖要用 libs.xxx,二者不能互换。AGP 8.0+ 要求所有插件都通过 alias() 声明,否则会报 Plugin with id '...' not found。
常见错误现象:
- 写成
id("org.jetbrains.kotlin.android") version "1.9.20"—— 这绕过了 catalog,版本无法集中管理 - 在
dependencies块里写implementation("androidx.core:core-ktx:1.12.0")而不是implementation(libs.core.ktx)—— 失去类型安全和重构支持 - 别名含下划线或大写字母(如
coreKtx)—— TOML 解析后转为点分命名(core.ktx),IDE 补全可能失效;建议全程用短横线(core-ktx)
模块级 build.gradle.kts 正确引用方式:
plugins {
alias(libs.plugins.kotlin.android) // ✅
}
dependencies {
implementation(libs.core.ktx) // ✅
testImplementation(libs.junit.api)
}
多模块项目升级依赖只需改一个地方,但要注意传递冲突
改 [versions] 里一个值,所有 libs.xxx 引用自动更新 —— 这是 catalog 最大价值。但 Gradle 仍按默认策略解析传递依赖,比如 A 模块依赖 libs.okhttp(v4.12.0),B 模块又显式声明 implementation("com.squareup.okhttp3:okhttp:4.11.0"),就会触发版本冲突。
这时候不能只靠 catalog,得配合 dependencyResolutionManagement 做约束:
- 在
settings.gradle.kts的dependencyResolutionManagement块中加versionCatalogs { create("libs") }(通常已默认存在) - 对易冲突组织(如
com.squareup)加force或requireSame(),例如:val okhttp by versions; force("com.squareup.okhttp3:okhttp:${okhttp.get()}") - 运行
./gradlew :app:dependencies --configuration releaseRuntimeClasspath查看实际解析树,确认是否真用了你期望的版本
真正容易被忽略的是:catalog 管理的是“声明”,不是“解析结果”。版本统一了,不代表运行时不会因传递依赖引入旧版类——这点比旧式 ext 变量更隐蔽。


















