「远程依赖」与「远程依赖 的依赖」冲突
把其中一个「远程依赖」以module的形式导入项目。
「本地module」与「主Module」发生远程依赖冲突
compileOnly 方式依赖,只会让依赖库参与编译,但不会参与打包
在「本地module」中,把发生冲突的库,以 compileOnly 依赖
只要确保有一个module中 该依赖能参与到打包即可。
常见问题
我们在写代码时候总会借鉴一些第三方库,有的是别人写的比较优秀的,有的则是google官方提供的,但是我们在依赖之后编译运行时候总会出各种各样的问题:
-
Error:Execution failed for task ':app:transformDexArchiveWithExternalLibsDexMergerForDebug'.
java.lang.RuntimeException: java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMergerException: Unable to merge dex
-
Error:Execution failed for task ':app:preDebugBuild'.
Android dependency 'com.android.support:appcompat-v7' has different version for the compile (27.0.2) and runtime (27.1.0) classpath. You should manually set the same version via DependencyResolution”
针对上面的support:appcompat库我们可以像下面一样子来指定自己所依赖的版本:
在 build.gradle 的 dependencies下面 添加如下代码即可
configurations.all {
resolutionStrategy.force 'com.android.support:support-annotations:26.1.0'
//循环一个个的依赖库
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
//获取当前循环到的依赖库
def requested = details.requested
//如果这个依赖库群组的名字是com.android.support
if (requested.group == 'com.android.support') {
//且其名字不是以multidex开头的
if (!requested.name.startsWith("multidex")) {
//这里指定需要统一的依赖版本
details.useVersion '27.1.0'
}
}
}
}
强制使用库中的版本
compile('com.squareup.okhttp:okhttp-mt:2.5.0') {
force = true
}
如上,我们在依赖okhttp的时候很可能发生冲突,就比如依赖的依赖中也包含了okhttp,这种场合下,就会产生版本冲突的问题,加上force = true表明的意思就是即使在有依赖库版本冲突的情况下坚持使用被标注的这个依赖库版本。
找到版本冲突的库
当项目越来越大,所使用的第三方库越来越多的时候,最让人头疼的是针对同一个库引入了多个不同的版本,编译的时候导致库冲突直接编译失败,问题找起来也很麻烦。还是利用resolutionStrategy,我们可以快速找到冲突的库以及各版本号,配置如下
configurations.all {
resolutionStrategy {
failOnVersionConflict()
}
}
比如 om.android.support:multidex 这个库引入了2个不同的版本:1.0.3 和 1.0.2
Conflict(s) found for the following module(s):
- com.android.support:multidex between versions 1.0.3 and 1.0.2
resolutionStrategy 统一全局第三方库版本
-
resolutionStrategy.force
我们在开发的过程当中,会依赖使用各种第三方库,比如说最常见的 appcompat-v7 库,不仅我们自己的代码里会依赖该库,而且有可能我们依赖的第三方库也会依赖该库,但是不同的地方依赖该库的版本号都有可能不一致,这样在编译的时候,整个项目当中会出现各种不同版本号的 appcompat-v7 库,编译的时候可能会报错。我们不可能修改第三方库里对 appcompat-v7 库依赖的版本号,那么我们可以通过 resolutionStrategy.force 来强制编译时统一库的版本号。
android {
configurations.all {
resolutionStrategy {
force 'com.android.support:appcompat-v7:28.0.0'
force 'com.android.support:support-v4:28.0.0'
}
}
}
-
resolutionStrategy.dependencySubstitution
还有一种这样的情形,假设一个第三方工具库叫 org.gradle:util:3.0,除了我们自己的项目以及部分第三方库也有依赖它,但是在实际使用的过程当中,发现该库有些功能不满足或者有bug,那这个时候该怎么办呢?一是提 issue 让该库的作者去修改,但是时间上来不及;二是源码拿过来本地进行修改,直接本地集成,但是要修改依赖方式,那么这个时候可以这样做:
假设我们本地 module 名称叫 :util
android {
configurations.all {
resolutionStrategy {
//远程依赖替换成本地依赖
substitute module('org.gradle:util:3.0') with project(':util')
//也可以将远程依赖换成另外的远程依赖,假设我们修改过的代码发布到自己的 maven 中央仓库后叫:com.xxx.xxx:util:3.0
//substitute module('org.gradle:util:3.0') with module('com.xxx.xxx:util:3.0')
}
}
}