Android中版本依赖冲突的那些问题

/ 0评 / 1

前言

在我们依赖其他三方库的时候,有时候Android Studio会有下图的提示。

All com.android.support libraries must use the exact same version specification (mixing versions can lead to runtime crashes). Found versions 28.0.0, 27.1.1. Examples include com.android.support:animated-vector-drawable:28.0.0 and com.android.support:support-media-compat:27.1.1 less... (Ctrl+F1) 
Inspection info:There are some combinations of libraries, or tools and libraries, that are incompatible, or can lead to bugs. One such incompatibility is compiling with a version of the Android support libraries that is not the latest version (or in particular, a version lower than your targetSdkVersion).  Issue id: GradleCompatible

虽然有时候不会导致打包出现问题,但是一个红线一直在也是很烦的。所以今天介绍下如何排查此问题以及如何解决。

查看项目依赖

根据上图中的提示,我们可以很简单的看到是因为我们使用的support库版本为28.0.0,但是项目中有一个support-media-compat版本为27.1.1,可能导致运行中Crash。

打印项目依赖图

我们可以如下图一样操作

或者在app目录下执行如下命令

//在app目录下,而不是项目根目录,将依赖保存到dependencies.txt方便查看
../gradlew dependencies > dependencies.txt

找到冲突的依赖

在上一步得到的依赖图中直接搜索support-media-compat即可,我们可以很清楚的看到,这个冲突是从com.ximalaya.ting.android.xmtrace:trace-developer这个三方库中带过来的,并且还有support-v4也是使用的27.1.1版本,也冲突了。

解决依赖冲突

1、直接排除掉其使用的依赖

implementation(com.ximalaya.ting.android.xmtrace:trace-developer:${versions.xmtrace}) {
    exclude group: 'com.android.support'
}

2、删排除group中的指定module

implementation(com.ximalaya.ting.android.xmtrace:trace-developer:${versions.xmtrace}) {
    exclude group: 'com.android.support', module: 'support-v4'
    exclude group: 'com.android.support', module: 'support-media-compat'
}

3、通过Grovvy脚本修改版本号解决冲突

android {
    configurations.all {
        resolutionStrategy.eachDependency { details ->
            def requested = details.requested
            if (requested.group == 'com.android.support') {
                if (requested.name.startsWith(support-v4)) {
                    details.useVersion '28.0.0'
                }
            }
        }
    }
}

补充

打印模块的所有依赖

./gradlew :app:dependencies

其中,app 需要替换成实际的模块名。

这样会把模块的所有 configuration 的依赖打印出来。

这种方式打印出的信息很多。通常,我们仅关心部分配置的依赖,可以通过下述方式打印特定 configureation 的依赖。

打印某个 configuration 的依赖

./gradlew dependencies --configuration prodDebugRuntimeClasspath

其中,prodDebugRuntimeClasspath 需要替换成实际想查看依赖的 configuration 名字。

注意,configuration 的组成格式如下:

<variant-name><Debug-or-Release><Runtime-or-Compile>Classpath

其中,Runtime 表示运行时所需要的依赖,Compile 表示编译时所需的依赖。

查看特定依赖的使用情况
如果知道依赖的名字,可以通过 dependencyInsight 打印出它在项目中的使用情况:用了哪个版本、如何被引入的等等。

./gradlew :app:dependencyInsight --configuration prodDebugRuntimeClasspath --dependency androidx.activity

上述命令是在 prodDebugRuntimeClasspath 这个 configuration 中查询依赖 androidx.activity 的使用情况。

另外补充

我们也可以通过代码获取,在项目根目录下添加如下代码
configuration 的组成格式如下

<variant-name><Debug-or-Release><Runtime-or-Compile>Classpath
task getReleasPackageThirdPartyDependencies {
    doLast {
        print project.findProject(":app").configurations
        project.findProject(":app").configurations.debugRuntimeClasspath.resolvedConfiguration.firstLevelModuleDependencies.each { dependency ->
            printDependency(dependency, "")
        }
    }
}

def printDependency(dependency, indent) {
    def fileSize = "unknow"
    if (dependency.moduleArtifacts[0] != null && dependency.moduleArtifacts[0].file != null) {
        fileSize = String.format("%.2f", dependency.moduleArtifacts[0].file.length() / 1024.0)
    }
    println "$indent${dependency.moduleGroup}:${dependency.moduleName}:${dependency.moduleVersion} ${fileSize}KB"
    dependency.children.each { childDependency ->
        printDependency(childDependency, indent + "    ")
    }
}

参考链接:https://blog.csdn.net/yuzhiqiang_1993/article/details/78214812

https://hjhl.github.io/android/gradle/print-dependencies-tree/

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注