版本目录
源:Gradle 官方文档 - Version Catalogs | Android 官方文档 - 迁移到版本目录
Version Catalog 是 Gradle 7.0+ 引入的依赖管理方案,通过集中式配置文件管理所有依赖版本,提供类型安全的依赖声明。
Version Catalog 简介
传统依赖管理的问题
分散的版本定义:
kotlin
// app/build.gradle.kts
dependencies {
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0")
}
// feature/build.gradle.kts
dependencies {
implementation("androidx.core:core-ktx:1.10.0") // 版本不一致!
}问题:
- 版本号分散在各个模块
- 容易出现版本不一致
- 升级困难且易出错
- 没有类型安全检查
Version Catalog 的优势
集中管理:
- 单一文件定义所有版本
- 跨模块版本一致性
- 便于统一升级
类型安全:
- IDE 自动补全
- 编译期错误检查
- 重构支持
依赖组:
- 将相关库打包为 bundle
- 简化常用组合
创建 Version Catalog
文件位置
标准位置:gradle/libs.versions.toml
自动识别:Gradle 7.4+ 自动识别并应用此文件
TOML 文件结构
toml
[versions]
# 版本号定义
[libraries]
# 库定义
[bundles]
# 依赖组定义
[plugins]
# 插件定义versions 版本号定义
基本定义
toml
[versions]
kotlin = "2.1.0"
compose = "1.7.5"
androidx-core = "1.15.0"
retrofit = "2.11.0"命名规范:
- 使用小写字母
- 单词间使用连字符
- - 语义清晰
版本号引用
toml
[versions]
kotlin = "2.1.0"
[libraries]
kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib", version.ref = "kotlin" }libraries 库定义
完整语法
toml
[libraries]
androidx-core = { group = "androidx.core", name = "core-ktx", version.ref = "androidx-core" }简化语法:
toml
[libraries]
androidx-core = { module = "androidx.core:core-ktx", version.ref = "androidx-core" }最简语法(版本直接写入):
toml
[libraries]
junit = "junit:junit:4.13.2"复杂示例
toml
[versions]
compose = "1.7.5"
compose-compiler = "1.5.8"
[libraries]
# Compose UI
compose-ui = { module = "androidx.compose.ui:ui", version.ref = "compose" }
compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose" }
compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "compose" }
compose-material3 = { module = "androidx.compose.material3:material3", version.ref = "compose" }
compose-material-icons = { module = "androidx.compose.material:material-icons-extended", version.ref = "compose" }
# Compose Foundation
compose-foundation = { module = "androidx.compose.foundation:foundation", version.ref = "compose" }
compose-runtime = { module = "androidx.compose.runtime:runtime", version.ref = "compose" }不指定版本
toml
[libraries]
# 使用 BOM 管理版本
compose-bom = "androidx.compose:compose-bom:2024.02.00"
compose-ui = { module = "androidx.compose.ui:ui" }
compose-material3 = { module = "androidx.compose.material3:material3" }bundles 依赖组
基本用法
toml
[versions]
retrofit = "2.11.0"
[libraries]
retrofit-core = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
retrofit-converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "retrofit" }
retrofit-converter-moshi = { module = "com.squareup.retrofit2:converter-moshi", version.ref = "retrofit" }
[bundles]
retrofit = ["retrofit-core", "retrofit-converter-gson", "retrofit-converter-moshi"]使用:
kotlin
dependencies {
implementation(libs.bundles.retrofit)
// 等同于
// implementation(libs.retrofit.core)
// implementation(libs.retrofit.converter.gson)
// implementation(libs.retrofit.converter.moshi)
}常用 bundle 示例
toml
[versions]
compose = "1.7.5"
lifecycle = "2.7.0"
[libraries]
# Compose
compose-ui = { module = "androidx.compose.ui:ui", version.ref = "compose" }
compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "compose" }
compose-material3 = { module = "androidx.compose.material3:material3", version.ref = "compose" }
compose-activity = "androidx.activity:activity-compose:1.9.3"
# Lifecycle
lifecycle-runtime = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycle" }
lifecycle-viewmodel = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "lifecycle" }
lifecycle-viewmodel-compose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "lifecycle" }
[bundles]
compose = ["compose-ui", "compose-ui-tooling-preview", "compose-material3", "compose-activity"]
lifecycle = ["lifecycle-runtime", "lifecycle-viewmodel", "lifecycle-viewmodel-compose"]plugins 插件定义
基本语法
toml
[versions]
agp = "8.7.3"
kotlin = "2.1.0"
[plugins]
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" }
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }使用:
kotlin
// build.gradle.kts (project)
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.kotlin.android) apply false
}kotlin
// app/build.gradle.kts
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose)
}在项目中使用
自动生成的访问器
库访问器规则:
toml
[libraries]
androidx-core-ktx = "androidx.core:core-ktx:1.15.0"转换为:
kotlin
libs.androidx.core.ktx转换规则:
-转为.- 驼峰命名
使用库
kotlin
// build.gradle.kts
dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
// Bundle
implementation(libs.bundles.compose)
// 测试
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.test.espresso.core)
}使用插件
kotlin
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
}完整配置示例
libs.versions.toml
toml
[versions]
# SDK
compileSdk = "35"
minSdk = "24"
targetSdk = "35"
# Plugins
agp = "8.7.3"
kotlin = "2.1.0"
ksp = "2.1.0-1.0.29"
# AndroidX
androidx-core = "1.15.0"
androidx-appcompat = "1.7.0"
androidx-activity = "1.9.3"
androidx-lifecycle = "2.7.0"
# Compose
compose-bom = "2024.12.01"
compose-compiler = "1.5.8"
# Network
retrofit = "2.11.0"
okhttp = "4.12.0"
# DI
hilt = "2.52"
# Testing
junit = "4.13.2"
androidx-test-ext = "1.2.1"
espresso = "3.6.1"
[libraries]
# AndroidX Core
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "androidx-core" }
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "androidx-appcompat" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "androidx-activity" }
# Lifecycle
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "androidx-lifecycle" }
androidx-lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "androidx-lifecycle" }
androidx-lifecycle-viewmodel-compose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "androidx-lifecycle" }
# Compose
compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "compose-bom" }
compose-ui = { group = "androidx.compose.ui", name = "ui" }
compose-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
compose-material3 = { group = "androidx.compose.material3", name = "material3" }
compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
# Network
retrofit-core = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" }
retrofit-converter-gson = { group = "com.squareup.retrofit2", name = "converter-gson", version.ref = "retrofit" }
okhttp-logging = { group = "com.squareup.okhttp3", name = "logging-interceptor", version.ref = "okhttp" }
# DI
hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" }
hilt-compiler = { group = "com.google.dagger", name = "hilt-compiler", version.ref = "hilt" }
# Testing
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidx-test-ext" }
androidx-test-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espresso" }
compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
[bundles]
compose = ["compose-ui", "compose-ui-graphics", "compose-ui-tooling-preview", "compose-material3"]
lifecycle = ["androidx-lifecycle-runtime-ktx", "androidx-lifecycle-viewmodel-ktx", "androidx-lifecycle-viewmodel-compose"]
retrofit = ["retrofit-core", "retrofit-converter-gson", "okhttp-logging"]
[plugins]
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" }
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }build.gradle.kts (project)
kotlin
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.android.library) apply false
alias(libs.plugins.kotlin.android) apply false
alias(libs.plugins.kotlin.compose) apply false
alias(libs.plugins.ksp) apply false
alias(libs.plugins.hilt) apply false
}build.gradle.kts (app)
kotlin
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose)
alias(libs.plugins.ksp)
alias(libs.plugins.hilt)
}
dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.androidx.activity.compose)
// Compose BOM
implementation(platform(libs.compose.bom))
implementation(libs.bundles.compose)
// Lifecycle
implementation(libs.bundles.lifecycle)
// Network
implementation(libs.bundles.retrofit)
// DI
implementation(libs.hilt.android)
ksp(libs.hilt.compiler)
// Testing
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.test.ext.junit)
androidTestImplementation(libs.androidx.test.espresso.core)
androidTestImplementation(platform(libs.compose.bom))
androidTestImplementation(libs.compose.ui.test.junit4)
// Debug
debugImplementation(libs.compose.ui.tooling)
debugImplementation(libs.compose.ui.test.manifest)
}迁移到 Version Catalog
从传统方式迁移
迁移前:
kotlin
// buildSrc/src/main/kotlin/Versions.kt
object Versions {
const val kotlin = "2.1.0"
const val compose = "1.7.5"
}
object Deps {
const val composeUi = "androidx.compose.ui:ui:${Versions.compose}"
}
// build.gradle.kts
dependencies {
implementation(Deps.composeUi)
}迁移后:
toml
# gradle/libs.versions.toml
[versions]
kotlin = "2.1.0"
compose = "1.7.5"
[libraries]
compose-ui = { module = "androidx.compose.ui:ui", version.ref = "compose" }kotlin
// build.gradle.kts
dependencies {
implementation(libs.compose.ui)
}自动迁移工具
Android Studio 提供迁移助手:
Tools → Version Catalog Migration
最佳实践
命名规范:
- 使用连字符分隔
- 语义清晰
- 保持一致性
版本号管理:
- 集中定义常用版本
- 相关库使用同一版本
- 定期更新
使用 bundles:
- 将常用组合定义为 bundle
- 简化依赖声明
- 便于统一管理
插件管理:
- 在 catalog 中定义插件版本
- 使用
alias引用 - 避免硬编码版本
团队协作:
- 提交
libs.versions.toml到版本控制 - 统一团队版本
- Code Review 时检查版本一致性