博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android Gradle 隐形依赖的奇怪案例
阅读量:6904 次
发布时间:2019-06-27

本文共 4563 字,大约阅读时间需要 15 分钟。

hot3.png

相信 Android 开发者都有在 Android Studio 中升级 compileSdkVersion 的经历,这个时候如果你使用了 support 包,并同时升级,那么可能会出现一个错误提示。本文教你如何解决这个问题。

在 Android Studio 中,Gradle 构建过程大多数都是抽象的。作为一个新手 Android 开发者,我们在使用 Gradle 的时候首先遇到的问题通常都是如何在 build.gradle 中添加远程依赖。

让我们来看一个情形并学习如何查看依赖树,以及解决依赖相关的问题。

我正在开发一个项目,并且我想把构建版本提升到最新的 API 27。同时,我把 build.gradle 中的 appcompat-v7 扩展库也升级到了 27.0.2.然后我 sync 项目,出现了如下错误:

输入图片说明

所有的 com.android.support 库都必须使用相同的版本 这个错误说我必须使用完全相同版本的扩展包。很直接,但是我的 build.gradle 中只有这一个扩展包。Android Studio 在说什么呢? ?上面提到的 com.android.support:animated-vector-drawable:27.0.2 和 com.android.support-v4:21.0.3 到底在哪?

输入图片说明

如果只有 build.gradle 中的依赖那么事情会变得很简单,但事实并非如此。这些依赖可能有一些别的依赖,别的依赖中又有另一些依赖等等等等。这就叫传递依赖,Gradle 需要把所有的这些直接/间接的依赖打包到 app 当中。Android Studio 的错误提示就是在说这些传递依赖。

Gradle 一定有某种方式来解决所有的依赖。哪个库要添加?如果两个不同的库都依赖于相同的库的不同版本呢?我们来深入了解一下发生了什么。

要查看依赖树(Gradle 解决依赖的方式),我们可以打开 Android Studio 的终端,然后输入以下命令(Windows):

gradlew app:dependencies```mac:

./gradlew app:dependencies

上面命令的输出是这样的:

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 默认选择那个库的最新版本。

| + — — com.android.support:support-v4:21.0.3 | | \ — — com.android.support:support-annotations:21.0.3 -> 27.0.2

上面显示的是尽管 support-v4:21.0.3 依赖于 support-annotations:21.0.3 ,但是有一个新版本 support-annotations:27.0.2 在依赖树中,所以 27.0.2 将会被使用。![输入图片说明](https://pic3.zhimg.com/80/v2-4d9379e8bffa05863479a6aa20cc75f1_hd.jpg "在这里输入图片标题")现在我们知道如何查看 Gradle 依赖树了,回到刚才的问题:所有的 com.android.support 库都必须使用完全相同的版本。所有的扩展包都在 com.android.support 组中,我们在上面的依赖树中可以看到 com.android.support:support-v4:21.0.3 只是 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 了。![输入图片说明](https://pic3.zhimg.com/80/v2-b13abb9d49da810238bc8f8f8d5462d5_hd.jpg "在这里输入图片标题")> 原文链接:[Android Gradle and the curious case of invisible dependency](http://https://proandroiddev.com/android-gradle-and-the-curious-case-of-invisible-dependency-7f1bcc8bb79e)

转载于:https://my.oschina.net/jpushtech/blog/1796057

你可能感兴趣的文章
mysql 登录权限
查看>>
Java之内部类
查看>>
怎样使用python帮助手册
查看>>
我的友情链接
查看>>
UITabelView的分割线处理及介绍
查看>>
Spring整合MyBatis
查看>>
打印机拒绝访问无法连接
查看>>
Linux学习路线图
查看>>
Linux系统下常见性能分析工具的使用
查看>>
事件驱动模型
查看>>
ASP.NET MVC 音乐商店 - 3. 视图与模型
查看>>
mcollective安装文档
查看>>
GRE隧道模式与IPSec传输模式构建×××
查看>>
linux命令6--touch命令
查看>>
我的友情链接
查看>>
且谈布局适配和日志框架
查看>>
在论坛中出现的比较难的sql问题:15(行转列2)
查看>>
springboot中的5种通知小例子
查看>>
mysql数据通过jdbc操作作为Spark数据源案例
查看>>
Sersync实现触发式文件同步
查看>>