文章 | Ashesh Bharadwajhtml
翻译 | 承香墨影android
受权 承香墨影 翻译、编辑并发布程序员
在 Android Studio 中,Gradle 构建过程对于开发者来讲,很大程度上是抽象的。做为一个新的 Android 开发者,咱们第一次遇到 Gradle 一般是在 build.gradle 文件中添加一个远程依赖项。shell
让咱们看看如何阅读 Gradle 依赖关系树,并解决与依赖关系有关的问题。api
这是我工做中管理的一个项目,我想将 targetVersion 升级到 27,我也在 Gradle 中,更新了新版的 appcompat-v7
支持库到最新的依赖版本 27.0.2
。在更改以后,同步项目,在 build.gradle 中出现如下错误提示:bash
该错误表示我必须使用彻底相同版本的支持库。但是我只在个人 build.gradle 中,使用了这个支持库。并发
Android Studio 的这个提示究竟是什么意思?app
这个错误提示中,说起到的 com.android.support:animated-vector-drawable:27.0.2
或com.android.support-v4:21.0.3
是在哪里又被引用了?post
若是只是应用程序的直接依赖库,只须要在 build.gradle 中指明依赖就行了,这样很是的清晰明了。可是实际状况并不是如此,这些依赖关系可能会进一步拥有本身的依赖关系,这被称为 依赖传递 。Gradle 须要在应用中包含全部的直接或者间接的依赖。学习
前面 Android Studio 提示的错误信息,正是咱们如今讨论的这些传递性依赖关系致使的。
Gradle 必须解决全部的这些依赖关系。包含使用了哪些库?若是两个不一样的库对同一个库有不一样版本的依赖关系,会发生什么问题?
要查看 Gradle 依赖关系树(Gradle 解析依赖关系的方式),咱们能够到位于 Android Studio 底部的 Terminal 选项卡并输入如下命令:
gradlew app:dependencies
复制代码
这将显示全部 构建变体 的依赖关系解析树。咱们能够在上面的命令中添加一个标识来查看特定构建变体的配置。例如 --configuration releaseCompileClasspath
将向咱们展现 release
变体的依赖树。
关于构建变体,建议阅读官方文档:
https://developer.android.com/studio/build/build-variants.html
以上是上述命令的输出:
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 (*)
复制代码
在查找目的以前,理解 Gradle 依赖关系树的格式很重要。
先来谈谈如下三个符号,它们的目的仅用于格式化:
+- - -
是依赖分支库的开始。|
标识仍是在以前的依赖库中的依赖,显示它依赖的库。\- - -
是依赖库的末尾。星号(*) 在依赖库的末尾,意味着该库的进一步依赖关系不会显示,由于它们已经列在其余某个子依赖树中。
最重要的标识是 ->
。
若是 Gradle 发现多个依赖库都依赖到同一个库可是不一样版本,那么它必须作出选择。毕竟包含同一个库的不一样版本是没有意义的。在这种状况下,Gradle 默认选择该库的最新版本。
例如:
| + — — com.android.support:support-v4:21.0.3
| | \ — — com.android.support:support-annotations:21.0.3 -> 27.0.2
复制代码
在上面,Gradle 告诉说,在 support-v4:21.0.3
依赖关系树中, support-annotations:21.0.3
依赖于更新的版本 support-annotations:27.0.2
,因此 27.0.2
将被使用。
如今咱们知道如何阅读 Gradle 依赖关系解析树,咱们回到本文的核心问题:全部 com.android.support 库必须使用彻底相同的版本。
全部支持库都属于如下组 com.android.support
。正如咱们在 Gradle 的依赖关系树中看到的那样,com.android.support:support-v4:21.0.3
是惟一具备版本 21.0.3
而且未解析到最新版本的支持库 27.0.2
,这就是形成冲突的缘由。
如何解决这个问题?有几种方式,能够作到这一点:
**一、经过 ResolutionStrategy **
经过 ResolutionStrategy 强制指定 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'
}
}
复制代码
关于 ResolutionStrategy 的具体细节,官方文档中有详细描述:
https://docs.gradle.org/current/dsl/org.gradle.api.artifacts.ResolutionStrategy.html
二、在 build.gradle 中指明版本
要在 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 中显式添加依赖关系彷佛更加的天然,而且能够留下注释。当咱们再次更新库来检查它是否仍然须要显式添加时,这个注释将提醒我关注它。
一旦添加并进行项目同步以后,错误文本将消失。如今,若是咱们再次运行依赖关系命令,咱们将看到support-v4:21.0.3
解决-> 27.0.2
。
大部分时候 Gradle 会正确解决依赖关系。而了解了 Gradle 的依赖关系,我想遇到这样的问题咱们应该更清楚如何去解决它。
我但愿这篇文章能让咱们更进一步了解 Gradle 依赖关系树和解决方案。
今天在公众号后台回复成长『成长』,将会获得我整理的一些学习资料,也能回复『加群』,一块儿学习进步。
原文连接: https://proandroiddev.com/android-gradle-and-the-curious-case-of-invisible-dependency-7f1bcc8bb79e
推荐阅读: