在遇到 依赖冲突 时 , 如果要 排查某个依赖的子库 时 , 就需要对该依赖库非常熟悉 , 最好是找出该依赖库位置 , 并 分析该依赖库的 Maven 配置文件 , 即 pom.xml 配置文件 ; 下面以 com.android.support:appcompat-v7 依赖库 为例进行演示 , 这个库经常会造成依赖冲突 ;
Android 官方提供的依赖库 , 都放在 SDK 的 extras 目录 下 , 如下图所示 :
其中 Android Support 依赖库的路径位置 , 在 D:\001_Develop\001_SDK\Sdk\extras\android\m2repository\com\android\support 路径中的依赖库如下图所示 :
这里以 appcompat-v7 依赖库为例 , 查看 23.3.0 版本的 com.android.support:appcompat-v7 依赖库 , 其目录为 D:\001_Develop\001_SDK\Sdk\extras\android\m2repository\com\android\support\appcompat-v7\23.3.0 , 依赖库内容如下 :
查看其 appcompat-v7-23.3.0.pom 依赖配置文件 , 发现该 pom 文件中有配置 com.android.support:support-v4 依赖 , pom 配置文件是 Maven 的依赖配置 , 其格式是 Xml 形式的 ;
<dependency>
<groupId>com.android.support</groupId>
<artifactId>support-v4</artifactId>
<version>23.3.0</version>
<type>aar</type>
<scope>compile</scope>
</dependency>
在 dependencies 中配置依赖时 , implementation 依赖配置 后 , 可以 在闭包中 使用 transitive 函数 设置依赖是否传递 ,
dependencies {
implementation ('androidx.appcompat:appcompat:1.4.1') {
transitive true // 包括传递依赖, 如果设置为 false 则排除传递依赖
}
}
ModuleDependency#transitive 函数的原型如下 :
/**
* 设置是否应解析此依赖项,包括或排除其可传递依赖项。
* 属于此依赖项的工件本身可能依赖于其他工件。
* 后者称为传递依赖。
*
* @param transitive 是否应解析可传递依赖项。
* @return this
*/
ModuleDependency setTransitive(boolean transitive);
针对依赖库冲突 : 依赖库 A 中 , 包含了 B , C 分库 ,
这就 出现了冲突 , 此时就会 引入了两个版本的 B 依赖库 , 导致了冲突 ;
在依赖库中 , 可以将其中的某个依赖库剔除 , 如 androidx.appcompat:appcompat
依赖库中 , 依赖了
androidx.annotation:annotation
依赖库androidx.core:core
依赖库ndroidx.cursoradapter:cursoradapter
依赖库androidx.activity:activity
依赖库+--- androidx.appcompat:appcompat:1.4.1
| +--- androidx.annotation:annotation:1.3.0
| +--- androidx.core:core:1.7.0 (*)
| +--- androidx.cursoradapter:cursoradapter:1.0.0
| +--- androidx.activity:activity:1.2.4
使用如下配置 , 在闭包中调用 ModuleDependency#exclude 方法 , 可以排除 androidx.activity:activity
依赖库 ;
设置之后 , 导入 androidx.appcompat:appcompat
依赖库 , 就会将 androidx.activity:activity
依赖库排除出去 , 不再加载该依赖库 ;
dependencies {
implementation ('androidx.appcompat:appcompat:1.4.1') {
// 排除 androidx.annotation:annotation 依赖
exclude group: "androidx.activity", module: "activity"
}
}
特别注意 : 如果在此处排除了 , 如果在其它地方引用了 androidx.appcompat:appcompat
依赖库 , 则该设置无效 ;
ModuleDependency#exclude 方法函数原型如下 :
/**
* 添加排除规则以排除此依赖项的可传递依赖项。
* <p>
* 排除特定的可传递依赖项并不保证它不会出现
* 在给定配置的依赖性中。
* 例如,没有任何排除规则的某些其他依赖项,
* 可能会引入完全相同的传递依赖关系。
* 确保从整个配置中排除可传递依赖项
* 请使用每个配置的排除规则:{@link configuration#getExcludeRules()}。
* 事实上,在大多数情况下,配置每个依赖项排除的实际意图
* 实际上是从整个配置(或类路径)中排除依赖项。
* <p>
* 如果您的意图是排除特定的可传递依赖关系
* 因为您不喜欢它引入配置的版本
* 然后考虑使用强制版本的功能:{@link ResolutionStrategy#force(Object…)}。
*
* <pre class='autoTested'>
* plugins {
* id 'java' // so that I can declare 'implementation' dependencies
* }
*
* dependencies {
* implementation('org.hibernate:hibernate:3.1') {
* //excluding a particular transitive dependency:
* exclude module: 'cglib' //by artifact name
* exclude group: 'org.jmock' //by group
* exclude group: 'org.unwanted', module: 'iAmBuggy' //by both name and group
* }
* }
* </pre>
*
* @param excludeProperties 定义排除规则的属性。
* @return this
*/
ModuleDependency exclude(Map<String, String> excludeProperties);
特别注意 : 如果在此处排除了 , 如果在其它地方引用了 androidx.appcompat:appcompat
依赖库 , 则该设置无效 ;
首先 , 执行
gradlew app:dependencies --configuration releaseRuntimeClasspath
命令 , 查看 androidx.appcompat:appcompat
依赖库中 , 包含 androidx.activity:activity
依赖库 , 如下图所示 ;
然后 , 在 configurations#configuration 脚本块 中 , 配置如下依赖配置 :
configurations {
configuration{
all*.exclude group: "androidx.activity", module: "activity"
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.4.1'
}
最后 , 再执行
gradlew app:dependencies --configuration releaseRuntimeClasspath
命令 , 查看 androidx.appcompat:appcompat
依赖库中 , 不再包含 androidx.activity:activity
依赖库 ;
在 configurations.all#resolutionStrategy 脚本块 中 , 可以 使用 force 强制指定依赖库 ;
使用如下代码 , 将 androidx.appcompat:appcompat
依赖库 , 强制指定为 1.2.0 版本 , 即使有更高版本的 androidx.appcompat:appcompat:1.4.
依赖库 , 也会强制使用该 androidx.appcompat:appcompat:1.2.0
低版本依赖库 ;
configurations.all {
resolutionStrategy {
force 'androidx.appcompat:appcompat:1.2.0'
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.4.1'
}
执行
gradlew app:dependencies --configuration releaseRuntimeClasspath
命令 , 查看 androidx.appcompat:appcompat
依赖库中 , 发现有 1.4.1 高版本依赖库 , 但是还是被强制使用了 1.2.0 版本的依赖库 ;