相信 Android 开发者都有在 Android Studio 中升级 compileSdkVersion 的经历,这个时候如果你使用了 support 包,并同时升级,那么可能会出现一个错误提示。本文教你如何解决这个问题。
在 Android Studio 中,Gradle 构建过程大多数都是抽象的。作为一个新手 Android 开发者,我们在使用 Gradle 的时候首先遇到的问题通常都是如何在 build.gradle 中添加远程依赖。
让我们来看一个情形并学习如何查看依赖树,以及解决依赖相关的问题。
我正在开发一个项目,并且我想把构建版本提升到最新的 API 27。同时,我把 build.gradle 中的 appcompat-v7 扩展库也升级到了 27.0.2.然后我 sync 项目,出现了如下错误:
命令行查看依赖:
gradlew app:dependencies
mac:
./gradlew app:dependencies
这会展示所有的依赖树。我们可以在上面的命令中添加一个标识来查看特定变体的配置。比如: --configuration releaseCompileClasspath
将会展示 release 变体的依赖树。
上面命令的输出大概是这样的:
releaseCompileClasspath - Resolved configuration for compilation for variant: release
+--- com.android.databinding:library:1.3.1
| +--- com.android.support:support-v4:21.0.3
| | \--- com.android.support:support-annotations:21.0.3 -> 27.0.2
| \--- com.android.databinding:baseLibrary:2.3.0-dev -> 3.0.1
+--- com.android.databinding:baseLibrary:3.0.1
+--- com.android.databinding:adapters:1.3.1
| +--- com.android.databinding:library:1.3 -> 1.3.1 (*)
| \--- com.android.databinding:baseLibrary:2.3.0-dev -> 3.0.1
+--- com.android.support.constraint:constraint-layout:1.0.2
| \--- com.android.support.constraint:constraint-layout-solver:1.0.2
\--- com.android.support:appcompat-v7:27.0.2
+--- com.android.support:support-annotations:27.0.2
+--- com.android.support:support-core-utils:27.0.2
| +--- com.android.support:support-annotations:27.0.2
| \--- com.android.support:support-compat:27.0.2
| +--- com.android.support:support-annotations:27.0.2
| \--- android.arch.lifecycle:runtime:1.0.3
| +--- android.arch.lifecycle:common:1.0.3
| \--- android.arch.core:common:1.0.0
+--- com.android.support:support-fragment:27.0.2
| +--- com.android.support:support-compat:27.0.2 (*)
| +--- com.android.support:support-core-ui:27.0.2
| | +--- com.android.support:support-annotations:27.0.2
| | \--- com.android.support:support-compat:27.0.2 (*)
| +--- com.android.support:support-core-utils:27.0.2 (*)
| \--- com.android.support:support-annotations:27.0.2
+--- com.android.support:support-vector-drawable:27.0.2
| +--- com.android.support:support-annotations:27.0.2
| \--- com.android.support:support-compat:27.0.2 (*)
\--- com.android.support:animated-vector-drawable:27.0.2
+--- com.android.support:support-vector-drawable:27.0.2 (*)
\--- com.android.support:support-core-ui:27.0.2 (*)
通过上面的样例就可以查出哪个依赖的包有问题,然后直接在 哪个builde下,把新版本的依赖单独写一遍就解决了这个问题。
在查看问题之前理解依赖树的格式是非常重要的。先来看看下面的三个符号,它们只是用来格式化的:
+ ---
是一个库分支的开始
|
表示继续显示这个库所依赖的分支
\---
表示分支的结束
(*)
在一个库的后面表示这个库的更多依赖没有显示,因为它们已经在其他子树中列出来了。
最重要的符号是 ->
在 Gradle 中如果多个库依赖于相同的库的不同版本,那么它会做出选择。包含库的不同版本是不合理的。因此,Gradle 默认选择那个库的最新版本。
| + — — com.android.support:support-v4:21.0.3
| | \ — — com.android.support:support-annotations:21.0.3 -> 27.0.2
怎么解决这个问题呢?有几种方式:
- 实现一个解决策略,让 Gradle 强制使用某个版本:
android {
configurations.all {
// To resolve the conflict for com.android.databinding:library:1.3.1
// dependency on support-v4:21.0.3
resolutionStrategy.force 'com.android.support:support-v4:27.0.2'
}
}
- 在 build.gradle 中显式添加
com.android.support:support-v4:27.0.2
,这样 Gradle 就会覆盖之前的旧版本。
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
// To resolve the conflict for com.android.databinding:library:1.3.1
// dependency on support-v4:21.0.3
implementation 'com.android.support:support-v4:27.0.2'
implementation 'com.android.support:appcompat-v7:27.0.2'
}
对于我来说,显式添加依赖看起来更加自然。在 build.gradle 中的注释会提醒我们再次更新时是否需要显式地添加这个依赖。
添加依赖后,再次 sync,错误提示就会消失了,现在我们再次运行命令会看到 support-v4:21.0.3
被标记为 -> 27.0.2
了。
原文链接: Android Gradle and the curious case of invisible dependency