前言
实际开发过程中不可避免的会使用到一些第三方,而我们引用的第三方可能会和我们使用的其他库产生冲突;或者由于其他原因需要对依赖进行剔除。
依赖冲突的解决方法其实很简单,主要就为以下两个步骤:
- 依赖分析,找到冲突的依赖。
- 剔除依赖或者强制使用某个版本的依赖。
依赖分析
查看依赖关系需要用到的命令为:gradlew :[module_name]:dependencies
如需分析工程中app这个module的依赖关系行命令则为 :gradlew :app:dependencies --configuration releaseRuntimeClasspath
从下面的关系树可以看到各个依赖之间的关系,以及依赖版本号合并后的最终版本号
1 2 3 4 5 6 7 8 9 10
| +--- com.android.support:support-core-utils:28.0.0 (*) | | | +--- com.android.support:customview:28.0.0 | | | | +--- com.android.support:support-annotations:28.0.0 | | | | \--- com.android.support:support-compat:28.0.0 (*) | | | +--- com.android.support:viewpager:28.0.0 | | | | +--- com.android.support:support-annotations:28.0.0 | | | | +--- com.android.support:support-compat:28.0.0 (*) | | | | \--- com.android.support:customview:28.0.0 (*) | | | +--- com.android.support:coordinatorlayout:28.0.0
|
如果你不想在命令终端中查看,而是想把依赖关系输出到文件中,则可以使用以下命令:
gradlew :[module_name]:dependencies > [output_file]。
例如将app module的依赖关系输出到dependence.txt文件中:
gradlew :app:dependencies > dependence.txt。

剔除依赖
通过移除某个第三方中特定的依赖。
使用exclude group:'group_name':module:'module_name' 方式剔除具体依赖,如果没有指定module_name则该group下所有的依赖都会被剔除,具体使用:
1 2 3 4 5 6 7 8 9
| //剔除rxpermissions这依赖中所有com.android.support相关的依赖,避免和我们自己的冲突 implementation 'com.github.tbruyelle:rxpermissions:0.10.2', { exclude group: 'com.android.support' exclude group: 'xxxxx' } //剔除 tm_navigation(这里是本地依赖)中依赖的springview implementation project(path: ':tm_navigation'),{ exclude group: 'com.liaoinstan.springview', module: 'library' }
|
关于group和module的概念,举一个例子就清楚了。
例如对于依赖implementation 'com.android.support:appcompat-v7:27.1.0'。
group为com.android.support,module为appcompat,版本号为27.1.0,同一个group下面可以有很多module的。
下面这种方式可以批量剔除整个工程中的相关依赖
1 2 3 4 5 6 7 8
| android{ //....
//剔除工程中所有的该依赖 configurations { all*.exclude group: 'org.hamcrest', module: 'hamcrest-core' } }
|
强制版本
有时候依赖传递层级过深或者数量过多,通过上面的方式则不能达到剔除的效果,这时候强制使用版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| android{ //.... } //根节点 configurations.all { resolutionStrategy.eachDependency { DependencyResolveDetails details -> def requested = details.requested if (requested.group == 'com.google.android.exoplayer') { if (!requested.name.startsWith("multidex")) { details.useVersion '2.9.3' } } } }
|
Jar包冲突
在实际使用过程中会遇到第三方中jar包冲突的情况,这些jar包是放在第三方依赖的libs目录中,并非gradle远端依赖。
例如第三方A引用了一个jar包,而另外一个第三方B也引用了同一个jar包,这两个jar包都是放在自己的libs目录。

此时可以通过直接删除文件的方式解决,在工程视角下找到需要处理的第三方依赖,右键jar包直接删除。
Jar包混淆后类名冲突
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| -injars 'classes.jar' -outjars 'classes-out.jar'
-dontskipnonpubliclibraryclassmembers -dontshrink -dontoptimize -dontusemixedcaseclassnames # 混淆前缀 -repackageclasses com.x -dontpreverify -dontnote -dontwarn -keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod
# 需要注意观察原始 jar 包中哪些是没有混淆的,需要保留 -keep class com.test.** {*;} # 因为我们的目的只是替换外层包名,类内部的一些东西都不用管 -keepclassmembers class ** {*;}
|
1 2
| cd xxxx\proguard-7.2.1\bin proguard.bat @convert.txt
|
aar中jar包