在Android开发过程中,我们会用到许多依赖库,包括官方和第三方库。为了避免依赖库版本冲突,并方便日后升级,我们需要对依赖库进行统一管理。
以前,我们常用以下几种方式管理依赖库。
- 比如,对于小 demo,统一在 app/build.gradle 里管理。
- 比如,新建一个 config.gradle 文件,在其内部定义 ext。
- 比如,使用 Kotlin + buildSrc。
今天,我们要介绍的是第四种方式,通过 Version Catalog 来管理依赖。Version Catalog 的中文名是“版本目录”。
我现在使用的 Android Studio Koala,在新建项目时默认就使用了 Version Catalog 来管理依赖。官方推荐的依赖库管理方案,值得信赖!
迁移步骤
接下来,我们说下迁移至 Version Catalog 的步骤。
新建文件
在根项目的 gradle 文件夹中,创建一个名为 libs.versions.toml 的文件,并将下列代码粘贴到文件里。
[versions]
agp = "8.5.1"
kotlin = "1.9.0"
coreKtx = "1.13.1"
junit = "4.13.2"
junitVersion = "1.2.1"
espressoCore = "3.6.1"
lifecycleRuntimeKtx = "2.8.3"
activityCompose = "1.9.0"
composeBom = "2024.04.01"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-ui = { group = "androidx.compose.ui", name = "ui" }
androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
粘贴完以后,目录结构是这样的。
迁移
对 app/build.gradle 的 plugins进行迁移。注意:迁移后是 alias ,而不是 id 。
//迁移前
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
}
//迁移后
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.jetbrains.kotlin.android)
}
下图是迁移前后 Git 的修改记录。
对 app/build.gradle.kts 的 dependencies进行迁移。
//迁移前
dependencies {
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0")
implementation("androidx.activity:activity-compose:1.8.2")
implementation(platform("androidx.compose:compose-bom:2023.08.00"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.compose.material3:material3")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
androidTestImplementation(platform("androidx.compose:compose-bom:2023.08.00"))
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest")
}
//迁移后
dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.ui)
implementation(libs.androidx.ui.graphics)
implementation(libs.androidx.ui.tooling.preview)
implementation(libs.androidx.material3)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)
}
下图是迁移前后 Git 的修改记录。
对 Project 的 build.gradle.kts 的 plugins进行迁移。注意:迁移后是 alias ,而不是 id 。
//迁移前
plugins {
id("com.android.application") version "8.2.0" apply false
id("org.jetbrains.kotlin.android") version "1.9.0" apply false
}
//迁移后
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.jetbrains.kotlin.android) apply false
}
下图是迁移前后 Git 的修改记录。
同步项目
同步完成后,Version Catalog 就会被应用到我们的项目中。在同步项目时,可能会遇到 Gradle 版本不支持的问题,这时需要升级 Gradle 版本。
使用事项
更新提示
当依赖库有新版本时,系统会提供更新提示。将光标悬停在提示色块上,即可直接选择更新到最新版本。
命名规范
libs.versions.toml 文件中的依赖项应采用 kebab case 命名法,例如 androidx-lifecycle-runtime-ktx 这样的格式。以下是 GPT 对 “kebab case 命名法” 的解释。
引用跳转
将光标悬停在 libs.versions.toml 文件中的依赖项命名上,然后执行 command+单击,可以直接跳转到该依赖项的引用位置。如果该依赖项有多个引用位置,系统会让你选择要跳转到的具体引用。
依赖方式
在 libs.versions.toml 文件中定义依赖项时,可以采用以下两种方式,两者在功能上是等价的:
- 使用
module简写方式,直接包含了group和name信息。 - 分开写
group和name。
例如:
// 简写方式
androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "coreKtx" }
// 分开写的方式
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
提醒:如果在将原始依赖转换为 libs.versions.toml 格式时觉得麻烦,可以借助 GPT 来完成。
使用 Bundles
在 libs.versions.toml 文件中,还可以定义 bundles,其作用是将多个依赖项组合成一个逻辑组。定义好这些依赖项组后,可以在 app/build.gradle 文件中引用。例如:
// 在 libs.versions.toml 文件中定义 bundles
[bundles]
androidx = ["androidx-core-ktx", "androidx-lifecycle-runtime-ktx"]
在 app/build.gradle 文件中引用方式如下:
dependencies { implementation(libs.bundles.androidx) }
同时,以下是对 versions、libraries、plugins 和 bundles 的解释:
- versions:在这个代码块中,定义用于保存依赖项和插件版本的变量,后续可以在
libraries和plugins中引用这些变量。 - libraries:在这个代码块中,定义具体的依赖项。
- plugins:在这个代码块中,定义具体的插件。
- bundles:在这个代码块中,定义一组依赖项,将多个依赖项组合成一个逻辑组,方便在
build.gradle文件中引用。
使用变量
在 libs.versions.toml 文件的 versions 部分添加相应的 minSdk 后,可以在设置 minSdk 时通过 libs.versions.minSdk.get().toInt() 进行引用。类似地,其他如 compileSdk、targetSdk 等也可以使用同样的方法进行引用,如下所示。
定义版本目录
libs.versions.toml 是 Version Catalog 文件的默认名称,Gradle 会默认在 gradle/libs.versions.toml 文件中查找目录。因此,只需将 libs.versions.toml 文件放置在 gradle 文件夹中,Gradle 就能找到并解析它,无需提前定义。
但是,如果你想将 Version Catalog 文件放置在项目的根目录,并修改其引用方式,则需要进行特殊定义。具体步骤如下:
- 在
settings.gradle文件中进行如下调整:
dependencyResolutionManagement {
versionCatalogs {
library {
from(files("library.versions.toml"))
}
}
}
- 将版本目录文件移动到项目根目录,并将文件名修改为
library.versions.toml。 - 修改引用位置,将之前的
libs前缀改为library前缀。例如:
dependencies {
implementation(library.androidx.core.ktx)
}
这样,Gradle 就会按照新的位置和命名方式来解析 Version Catalog 文件。
版本限制
Version Catalog 对 Gradle 的版本是有要求的,实操时需要注意下。
总结
通过使用 Version Catalog,我们可以更高效地管理项目中的依赖库,避免版本冲突,并简化依赖库的升级过程。希望这篇文章对你有所帮助。
如果你有任何问题或建议,欢迎提出!
参考资料
- Google 官方 Demo. (n.d.). Nowinandroid. github.com/android/now…
- Gradle 官方文档. (n.d.). Sharing Dependency Versions between Projects. docs.gradle.org/current/use…
- Google 开发者文档. (n.d.). 将 Build 迁移到版本目录. developer.android.com/build/migra…