问题
在出现依赖的库版本不一致的情况时,gradle会默认使用新版本覆盖旧版本,通常不需要手动去解决。那么出现冲突一般为两个依赖属于不同类型的配置,比如:
compile 'junit:junit:4.12' //denpends on version 1.3
androidTestCompile 'org.mockito:mockito-core:1.10.19' //denpends on version 1.1
解决方法
打印依赖树
将依赖关系打印到日志文件中: ./gradlew -q app:dependencies > dependencies.txt
,结合出错信息找到冲突的库,一般情况下试着将冲突的的库升级到最新版本就可以解决问题,通常会有版本提示,如果没有可以在Marven中查找
防止依赖传递transitive = false
#关闭单个库的传递依赖
api('xxx.xxx.xxx:1.1.9'){
transitive = false
}
#关闭全局传递依赖
configurations.all {
transitive = false
}
排除依赖exclude
相当于更小粒度的限制传递依赖。exclude可以接收group和module两个参数,这两个参数可以单独使用也可以搭配使用
// group :module:version
android.arch.lifecycle:runtime:1.1.1
dependencies {
#测试时发现exclude在dependencies中单独为某一个库设置没办法正常工作
# compile("pkaq.tiger:web:1.0") {
# exclude module: 'share'
# }
#}
#推荐使用configurations来配置
configurations {
//编译期排除commons模块
compile.exclude module: 'commons'
//在整个构建过程中排除pkaq.tiger:share
all*.exclude group: 'pkaq.tiger', module: 'share'
}
使用场景:
- 依赖冲突时,如果有两个依赖引用了相同jar包的不同版本时,默认情况下gradle会采用最新版本的jar包,此时可以通过排除选项来排除。
- 运行期无需此模块的。
- 无法正常获取到此传递依赖,远程仓库都不存在的。
- 版权原因需要排除的。
- 其他原因。
使用强制版本force
当然,有时候你可能仅仅是需要强制使用某个统一的依赖版本,而不是排除他们,那么此时force就该登场了。指定force = true属性可以冲突时优先使用该版本进行解决。
#测试无效
#compile('org.hibernate:hibernate:3.1') {
# force = true
#}
#全局配置
configurations.all {
resolutionStrategy.force 'com.google.guava:guava:18.0'
}
使用动态版本
如果你想让你的工程始终采用最新依赖,那么Gradle提供了一种方式可以始终保证采用依赖的最新版本而无需每次手工检查修改版本。使用加号+,可以让Gradle在每次执行构建时检查远程仓库,如果存在新版本则下载选用最新版本。
当然也可以指定依赖某个大版本下的最新子版本,1.+表示始终采用该依赖最新的1.x版本的最新依赖。
compile 'org.springframework:spring-web:+'
虽然这是看上去十分风骚的一种用法,但这无疑会降低你系统构建的速度同时提高构建失败的风险。因为Gradle不得不每次检查远程仓库是否存在最新版本,同时新版本也可能带来无法预知的兼容性问题,比如quartz2.x较之于quartz1.x,common-lang3较之于common-lang等。
综合示例
compile('org.hibernate:hibernate:3.1') {
// 冲突时优先使用该版本
force = true
// 依据构建名称排除
exclude module: 'cglib'
// 依据组织名称排除
exclude group: 'org.jmock'
// 依据组织名称+构件名称排除
exclude group: 'org.unwanted', module: 'iAmBuggy'
// 为本依赖关闭依赖传递特性
transitive = false
}
参考文章:
https://blog.csdn.net/pkaq_/article/details/53906668
https://www.jianshu.com/p/9b6d71e3c6fd
网友评论