您的构建文件指定了您的直接依赖项,但每个依赖项都可能需要其他依赖项。这些传递依赖项会快速扩展您的整体依赖项图,通常会出现版本冲突。
当minor
(新功能)或patch
(错误修复)部分发生变化时,库仍然可能兼容,并且不太可能影响您的应用。
例如,假设您的应用依赖于库 A 和库 B,而库 A 和库 B 又依赖于库 C 的不同版本。
在这种情况下,Gradle 默认选择库 C 的最新版本,这可能会导致编译或运行时问题。在此示例中,库 C 解析为 2.1.1,但请注意,库 A 请求了库 C 1.0.3。版本号的 major 部分已更改,表示不兼容的更改,例如删除的功能或类型。这可能导致从库 A 发出的调用崩溃。
您的应用可能具有既是直接依赖项又是传递依赖项的依赖项。
在这种情况下,较新的传递依赖项可以覆盖您在应用中直接请求的版本。
Gradle 会查看图中所有依赖项的所有候选版本,以确定每个依赖项的最新版本。您可以使用 基本的 Gradle 任务 和 更高级的工具 来确定 Gradle 已解析的每个依赖项的版本。比较此解析中的更改是理解和降低升级风险的关键。
例如,您可以使用 Gradle 的 dependencies
任务,通过运行 ./gradlew app:dependencies
来显示应用程序模块使用的所有依赖项的树状结构。针对使用图 2 中所示库的应用程序运行此命令,我们会看到
1: releaseRuntimeClasspath - Runtime classpath of /release.
2: +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.0
3: | +--- ... (omitted for brevity) ...
4: +--- com.sample:library.a:1.2.3
5: | +--- com.sample:library.c:2.1.1
6: | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.0.0 (*)
7: | \--- org.jetbrains.kotlin:kotlin-stdlib:2.0.0 (*)
8: +--- com.sample:library.c:1.4.1 -> 2.1.1 (*)
报告的这部分显示了为 releaseRuntimeClasspath
配置解析的一些依赖项。
在您的依赖项报告中,每当看到 ->
时,表示请求者(您的应用程序或其他库)使用了它未预期的某个依赖项版本。在许多情况下,这不会导致任何问题,因为大多数库都是为向后兼容性而编写的。但是,某些库可能会进行不兼容的更改,此报告可以帮助您确定应用程序行为出现的新问题来自哪里。
有关使用 Gradle 依赖项报告的更多详细信息,请参阅 查看和调试依赖项。
您可以直接指定请求的版本、在版本目录中指定或在物料清单 (BOM) 中指定。
直接版本规范解析
您指定的依赖项版本将成为版本解析的候选版本。
例如,要在您的 app/build.gradle.kts
中将 androidx.compose.ui:ui
库的 1.7.3 版本作为依赖项请求
dependencies {
implementation("androidx.compose.ui:ui:1.7.3")
}
版本 1.7.3 将成为候选版本。Gradle 会在 1.7.3 和传递依赖项请求的同一库的其他版本中解析最新版本。
版本目录解析
版本目录定义变量以跟踪整个应用程序中使用的依赖项版本。如果您使用版本目录中的变量,则该变量指定的依赖项将添加到版本解析的候选版本中。版本目录中未使用的变量将被忽略。
例如,要在您的 gradle/libs.versions.toml
文件中将 androidx.compose.ui:ui
的 1.7.3 版本作为依赖项指定
[versions]
ui = "1.7.3"
[libraries]
androidx-compose-ui = { group = "androidx.compose.ui", name = "ui", version.ref = "ui" }
这定义了一个名为 libs.androidx.compose.ui
的变量来表示该库。除非您使用该变量来指定依赖项,否则此版本不会被视为候选版本。
要在您的 app/build.gradle.kts
中请求该库及其版本
dependencies {
implementation(libs.androidx.compose.ui)
}
Gradle 的解析方式与直接规范相同。
物料清单 (BOM) 解析
BOM 中出现的所有库的版本都将成为版本解析的候选版本。请注意,仅当库被指定为直接或间接依赖项时才会被使用。BOM 中的其他库将被忽略。
BOM 版本会影响您的直接依赖项以及 BOM 中出现的所有传递依赖项。
例如,在您的 app/build.gradle.kts
中将 BOM 指定为平台依赖项
dependencies {
implementation(platform("androidx.compose:compose-bom:2024.10.00"))
implementation("androidx.compose.ui:ui")
}
您要作为依赖项使用的任何库都不需要版本规范;请求的版本来自 BOM。
请注意,您还可以使用版本目录为 BOM 和库创建变量。对于出现在 BOM 依赖项中的库,请在版本目录中省略版本号。
例如,您的版本目录包含 BOM 及其版本号,但未为从 BOM 中引用的库指定版本
[versions]
composeBom = "2024.10.00"
[libraries]
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-compose-ui = { group = "androidx.compose.ui", name = "ui" }
您的 app/build.gradle.kts
使用版本目录中定义的变量引用 BOM 和库
dependencies {
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.compose.ui)
}
BOM 中指定的该库的版本将成为 Gradle 解析的候选版本。此外,BOM 中指定的其他所有库版本都将成为候选版本,无论您是否将其直接用作依赖项。
例如,假设 BOM 为库 A、B 和 C 指定了版本。您的应用程序希望直接使用库 A 作为依赖项,以及库 D。库 D 使用库 B 作为依赖项。没有任何内容使用库 C。
库 A、B 和 D 是应用程序中的依赖项;库 C 被忽略。Gradle 使用 BOM 中指定的 A 和 B 的版本作为候选版本,即使您没有直接将库 B 指定为依赖项。
如果库 D 请求的库 B 版本低于 2.0.1,则 Gradle 会解析为 2.0.1。如果库 D 请求的库 B 版本更高,则 Gradle 会解析为该版本。