前言
实际开发过程中不可避免的会使用到一些第三方,而我们引用的第三方可能会和我们使用的其他库产生冲突;或者由于其他原因需要对依赖进行剔除。
依赖冲突的解决方法其实很简单,主要就为以下两个步骤:
- 依赖分析,找到冲突的依赖。
- 剔除依赖或者强制使用某个版本的依赖。
依赖分析
查看依赖关系需要用到的命令为:gradlew :[module_name]:dependencies
如需分析工程中app这个module的依赖关系行命令则为 :gradlew :app:dependencies --configuration releaseRuntimeClasspath
从下面的关系树可以看到各个依赖之间的关系,以及依赖版本号合并后的最终版本号
+--- 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下所有的依赖都会被剔除,具体使用:
//剔除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的。
下面这种方式可以批量剔除整个工程中的相关依赖
android{
//....
//剔除工程中所有的该依赖
configurations {
all*.exclude group: 'org.hamcrest', module: 'hamcrest-core'
}
}
强制版本
有时候依赖传递层级过深或者数量过多,通过上面的方式则不能达到剔除的效果,这时候强制使用版本
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包混淆后类名冲突
下载新版本 proguard Releases · Guardsquare/proguard (github.com)
创建
convert.txt
,输入如下内容:
-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 ** {*;}
- 执行如下命令:
cd xxxx\proguard-7.2.1\bin
proguard.bat @convert.txt
aar中jar包