这个问题在使用eclipse进行开发时就存在,只不过当时大部分引入的是jar包,直接检查即可排除包重复的问题; 后来使用Android Studio进行开发,用上了gradle来管理项目的依赖,很方便,极大减少工作量,一句话即可引入;
然而,最近在查看一个运行的项目时,无意间瞥见了这个:
完全懵圈了啊,为什么呢
明明项目里都统一指定了support库的版本号为25.0.0,为什么还是有25.2.0,更有甚者还有23.3.0,24.2.1,这都是什么情况? 后来查了下,第三方库也存在依赖库,项目依赖的第三方库越多,这种情况就越明显,根本控制不了了吗?错错错,我们还是有办法的,强大的gradle连这点东西都摆平不了,怎么对得起那么慢点构建速度呢—。—
下面我们分几步来操作: 第一步:项目根目录下执行命令:
./gradlew :app:dependencies --configuration compile
命令解释 app:dependencies ## 打印所有依赖库 app:dependencies --configuration compile ## 打印编译时的依赖库
app:dependencies --configuration runtime ## 打印运行时的依赖库
dependency任务执行完会打印出这个:
也就是module-app 的依赖树,显示了项目的build脚本声明的顶级依赖和传递依赖; 意义:
版本:唯一的依赖。 版本():还存在该库其他版本的依赖或者间接依赖,并且默认选择()所标注的版本。 版本1->版本2():还存在该库其他版本的依赖或者间接依赖,并且选择 版本2。
第二步:使用exclude 排除依赖; 使用方法:
compile (group: 'foo', name: 'foo', version: '0.1') { exclude group:'groupName' module:'modelName'}
举例:
compile('com.facebook.fresco:fresco:0.10.0') { exclude module: 'support-v4' }
最后,其实有更完善的思路
a. 利用传递依赖特性 -例如a.jar依赖b.jar,在Gradle中,只需添加a.jar即可,Gradle将自动把a依赖的所有库全部下载。 或者可手动配置transitive属性为false,阻止依赖的下载
dependencies { // transitive 属性默认为 true compile group:'log4j',name:'log4j',version:'1.2.17',transitive:false}
-可能存在依赖传递的版本冲突问题,所以需要2中提到的 exclude,手动排除
为了解决Gradle冲突有以下几种方式 (1) 最近版本策略(默认):使用最新版本,gradle自动选择; (2) 冲突失败策略:发生冲突时,编译失败,需要手动配置 (3) 强制指定版本策略:发生冲突时,提前指定版本
举例如下:
/* 冲突失败策略设置*/configurations.all { resolutionStrategy { failOnVersionConflict() }}/* 强制指定版本策略设置*/dependencies { compile group:'b',name:'b',version:'1.1',force:true}
b. 使用动态依赖特性
需要手动配置,举例如下:
dependencies { /* 选择1以上任意一个版本,这使发生版本冲突的几率变小*/ compile group:'b',name:'b',version:'1.+' /* 选择最新的版本,避免直接指定版本号 */ compile group:'a',name:'a',version:'latest.integration'}
c.其他特性
指定库文件类型
// ext 默认jar,可选属性为war、zipcompile group:'b',name:'b',version:'1.1',ext:'war'``使用分类器(classifiers)
// 例如提供了2种包,a-1.0-dev.war, a-1.0-dev.jar compile group:'b',name:'b',version:'1.1',classifier:'dev',ext:'war' ``
替换传递依赖的版本
compile group:'a',name:'a',version:'l.0' { dependencies 'b:b:1.1'}