Sir zach

专注于算法,AI, Android以及音视频领域 欢迎关注我的最新博客: zachliu.cn

导航

【原创】解决Multiple dex files define问题的思路

Posted on 2021-04-19 17:19  SirZach  阅读(847)  评论(0编辑  收藏  举报

Multiple dex files define Landroid/support/v4/media/MediaMetadataCompat$Builder;

工作中我们可能会遇到各种 muxtiple dex files define的问题。本文主要来分析此类问题需要如何解决。

下面是build.gradle信息

compileSdkVersion 26
defaultConfig {
    minSdkVersion 21
    targetSdkVersion 22
    versionCode 100
    versionName "1.0.0"
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation project(':tm.libs')

    implementation 'com.android.support:appcompat-v7:26.1.0'  // 此处有一个红色告警
    implementation 'com.android.support:design:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'

    implementation ('com.google.android.exoplayer:exoplayer-core:2.9.6'
    implementation ('com.google.android.exoplayer:exoplayer-ui:2.9.6'
    implementation 'com.googlecode.mp4parser:isoparser:1.1.21'

    implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
    implementation 'io.reactivex.rxjava2:rxjava:2.2.5'
}

红色告警内容, 意思是com.android.support中存在多版本依赖,可能导致运行时崩溃:

All com.android.support libraries must use the exact same version specification (mixing versions can lead to runtime crashes). 
Found versions 27.1.1, 26.1.0. Examples include `com.android.support:support-compat:27.1.1` and `com.android.support:animated-vector-drawable:26.1.0`

遇到这个错误,我们大概是知道原因可能是工程中引用的第三库存在重复依赖的情况。 我们要做的就是如果找到重复依赖的库. 我们可以使用gradlew命令查看依赖,或者直接使用AS提供的工具直接查看。
在Gradle标签下,找到所在工程下面的 dependencies, 双击执行这个任务

如果你的代码没有其他其他编译错误的话,可以看到下面的依赖信息

debugAndroidTestCompileClasspath - Resolved configuration for compilation for variant: debugAndroidTest
+--- project :tm.libs
+--- com.android.support:appcompat-v7:26.1.0
|    +--- com.android.support:support-annotations:26.1.0 -> 27.1.1
|    +--- com.android.support:support-v4:26.1.0
|    |    +--- com.android.support:support-compat:26.1.0 -> 27.1.1
|    |    |    +--- com.android.support:support-annotations:27.1.1
|    |    |    \--- android.arch.lifecycle:runtime:1.1.0
|    |    |         +--- android.arch.lifecycle:common:1.1.0
|    |    |         \--- android.arch.core:common:1.1.0
|    |    +--- com.android.support:support-media-compat:26.1.0 -> 27.1.1
|    |    |    +--- com.android.support:support-annotations:27.1.1
|    |    |    \--- com.android.support:support-compat:27.1.1 (*)
|    |    +--- com.android.support:support-core-utils:26.1.0
|    |    |    +--- com.android.support:support-annotations:26.1.0 -> 27.1.1
|    |    |    \--- com.android.support:support-compat:26.1.0 -> 27.1.1 (*)
|    |    +--- com.android.support:support-core-ui:26.1.0
|    |    |    +--- com.android.support:support-annotations:26.1.0 -> 27.1.1
|    |    |    \--- com.android.support:support-compat:26.1.0 -> 27.1.1 (*)
|    |    \--- com.android.support:support-fragment:26.1.0
|    |         +--- com.android.support:support-compat:26.1.0 -> 27.1.1 (*)
|    |         +--- com.android.support:support-core-ui:26.1.0 (*)
|    |         \--- com.android.support:support-core-utils:26.1.0 (*)
|    +--- com.android.support:support-vector-drawable:26.1.0
|    |    +--- com.android.support:support-annotations:26.1.0 -> 27.1.1
|    |    \--- com.android.support:support-compat:26.1.0 -> 27.1.1 (*)
|    \--- com.android.support:animated-vector-drawable:26.1.0
|         +--- com.android.support:support-vector-drawable:26.1.0 (*)
|         \--- com.android.support:support-core-ui:26.1.0 (*)
+--- com.android.support:design:26.1.0
|    +--- com.android.support:support-v4:26.1.0 (*)
|    +--- com.android.support:appcompat-v7:26.1.0 (*)
|    +--- com.android.support:recyclerview-v7:26.1.0
|    |    +--- com.android.support:support-annotations:26.1.0 -> 27.1.1
|    |    +--- com.android.support:support-compat:26.1.0 -> 27.1.1 (*)
|    |    \--- com.android.support:support-core-ui:26.1.0 (*)
|    \--- com.android.support:transition:26.1.0
|         +--- com.android.support:support-annotations:26.1.0 -> 27.1.1
|         \--- com.android.support:support-v4:26.1.0 (*)
+--- com.android.support.constraint:constraint-layout:1.1.3
|    \--- com.android.support.constraint:constraint-layout-solver:1.1.3
+--- com.google.android.exoplayer:exoplayer-core:2.9.6
|    \--- com.android.support:support-annotations:27.1.1
+--- com.google.android.exoplayer:exoplayer-ui:2.9.6
|    +--- com.google.android.exoplayer:exoplayer-core:2.9.6 (*)
|    +--- com.android.support:support-media-compat:27.1.1 (*)
|    \--- com.android.support:support-annotations:27.1.1
+--- com.googlecode.mp4parser:isoparser:1.1.21
+--- io.reactivex.rxjava2:rxandroid:2.1.0
|    \--- io.reactivex.rxjava2:rxjava:2.2.0 -> 2.2.5
|         \--- org.reactivestreams:reactive-streams:1.0.2
\--- io.reactivex.rxjava2:rxjava:2.2.5 (*)

可以看到,部分依赖后面标注了(*)号, 表示此依赖会被忽略。 -> 表示此依赖由原版本修改到了新版本。

如果你无视告警,直接运行的话,会报下面的错误

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tsing.mediaplayer/com.tsingtech.player.MainActivity}: android.view.InflateException: Binary XML file line #0: Binary XML file line #0: Error inflating class com.google.android.exoplayer2.ui.PlayerView

...
  Caused by: java.lang.NoSuchMethodError: No static method getFont(Landroid/content/Context;ILandroid/util/TypedValue;ILandroid/widget/TextView;)Landroid/graphics/Typeface; in class Landroid/support/v4/content/res/ResourcesCompat; or its super classes (declaration of 'android.support.v4.content.res.ResourcesCompat' appears in /data/app/com.tsing.mediaplayer-1/base.apk)

通过build.gradle可知,我们期望的com.android.support:appcompat 版本和design版本均为26.1.0, 但是support-media-compat, support-annotations 和support-compat被修改成了27.1.1,也就是说gradle会自动寻找当前匹配库的最高版本进行依赖。 再结合上面的红色告警信息,表示support-compat库可能存在冲突。 再结合最初的Muxtiple dex错误,确认MediaMetadataCompat所在包正好在support-media-compat

image

我们已经知道了重复依赖所在的包,解决办法就是将你不需要的包从依赖中排除即可。

implementation ('com.google.android.exoplayer:exoplayer-core:2.9.6') {
	exclude module: 'support-annotations'
}
implementation ('com.google.android.exoplayer:exoplayer-ui:2.9.6') {
	exclude module: 'support-media-compat'
	exclude module: 'support-annotations'
}

查看一下现在的依赖关系:

debugAndroidTestCompileClasspath - Resolved configuration for compilation for variant: debugAndroidTest
+--- project :tm.libs
+--- com.android.support:appcompat-v7:26.1.0
|    +--- com.android.support:support-annotations:26.1.0
|    +--- com.android.support:support-v4:26.1.0
|    |    +--- com.android.support:support-compat:26.1.0
|    |    |    +--- com.android.support:support-annotations:26.1.0
|    |    |    \--- android.arch.lifecycle:runtime:1.0.0
|    |    |         +--- android.arch.lifecycle:common:1.0.0
|    |    |         \--- android.arch.core:common:1.0.0
|    |    +--- com.android.support:support-media-compat:26.1.0
|    |    |    +--- com.android.support:support-annotations:26.1.0
|    |    |    \--- com.android.support:support-compat:26.1.0 (*)
|    |    +--- com.android.support:support-core-utils:26.1.0
|    |    |    +--- com.android.support:support-annotations:26.1.0
|    |    |    \--- com.android.support:support-compat:26.1.0 (*)
|    |    +--- com.android.support:support-core-ui:26.1.0
|    |    |    +--- com.android.support:support-annotations:26.1.0
|    |    |    \--- com.android.support:support-compat:26.1.0 (*)
|    |    \--- com.android.support:support-fragment:26.1.0
|    |         +--- com.android.support:support-compat:26.1.0 (*)
|    |         +--- com.android.support:support-core-ui:26.1.0 (*)
|    |         \--- com.android.support:support-core-utils:26.1.0 (*)
|    +--- com.android.support:support-vector-drawable:26.1.0
|    |    +--- com.android.support:support-annotations:26.1.0
|    |    \--- com.android.support:support-compat:26.1.0 (*)
|    \--- com.android.support:animated-vector-drawable:26.1.0
|         +--- com.android.support:support-vector-drawable:26.1.0 (*)
|         \--- com.android.support:support-core-ui:26.1.0 (*)
+--- com.android.support:design:26.1.0
|    +--- com.android.support:support-v4:26.1.0 (*)
|    +--- com.android.support:appcompat-v7:26.1.0 (*)
|    +--- com.android.support:recyclerview-v7:26.1.0
|    |    +--- com.android.support:support-annotations:26.1.0
|    |    +--- com.android.support:support-compat:26.1.0 (*)
|    |    \--- com.android.support:support-core-ui:26.1.0 (*)
|    \--- com.android.support:transition:26.1.0
|         +--- com.android.support:support-annotations:26.1.0
|         \--- com.android.support:support-v4:26.1.0 (*)
+--- com.android.support.constraint:constraint-layout:1.1.3
|    \--- com.android.support.constraint:constraint-layout-solver:1.1.3
+--- com.google.android.exoplayer:exoplayer-core:2.9.6
+--- com.google.android.exoplayer:exoplayer-ui:2.9.6
|    \--- com.google.android.exoplayer:exoplayer-core:2.9.6
+--- com.googlecode.mp4parser:isoparser:1.1.21
+--- io.reactivex.rxjava2:rxandroid:2.1.0
|    \--- io.reactivex.rxjava2:rxjava:2.2.0 -> 2.2.5
|         \--- org.reactivestreams:reactive-streams:1.0.2
\--- io.reactivex.rxjava2:rxjava:2.2.5 (*)

已经没有了 27.1.1的依赖,上面的红色告警也消失了。同理,其他的multiple dex define问题, 也可以用这个方法来根本解决!