Gradle for Android(三)——依赖管理(二)

来源:互联网 发布:树莓派部署python环境 编辑:程序博客网 时间:2024/06/08 01:57

上一章节我们详细分析了Gradle依赖的基本用法,本章做一个扩展,讨论下Gradle的依赖配置问题。主要讨论的内容有依赖的基本配置项(compile,provided,testCompile等),基于BuildType和Flavor的依赖配置,以及依赖关系的设置。

依赖配置

在Gradle中,依赖是按照指定名称进行分类的,这些分类被称为配置项,我们可以使用配置项声明项目的外部依赖。

Java插件指定了若干依赖配置项,其描述如下:

  • compile:默认,compile是对所有的build type以及favlors都会参与编译并且打包到最终的apk文件中。
  • apk:只会打包到apk文件中,而不参与编译,所以不能再代码中直接调用jar中的类或方法,否则在编译时会报错。
  • provided:provided是对所有的build type以及favlors只在编译时使用,类似eclipse中的external-libs,只参与编译,不打包到最终apk。
  • testCompile:仅仅是针对单元测试代码的编译编译以及最终打包测试apk时有效,而对正常的debug或者release apk包不起作用。
  • androidTestCompile
  • Debug compile:Debug compile 仅仅针对debug模式的编译和最终的debug apk打包。
  • Release compile:Release compile 仅仅针对Release 模式的编译和最终的Release apk打包。

注:testCompile和androidTestCompile会添加额外的library支持针对测试。

这些配置将会被用在测试相关的tasks中,这会对添加测试框架例如JUnit或者Espresso非常有用,因为你只是想让这些框架们能够出现在测试apk中,而不是生产apk中。

除了这些特定的配置外,Android插件还为每个构建变体提供了配置,这让debugCompile或者releaseProvided等配置成为可能。如果你想针对你的debug版本添加一个logging框架,这将很有用。这些内容的详细介绍,我会在下一个博客里详细介绍。

图形化操作如图:

这里写图片描述

管理依赖的版本

传递依赖

在Maven仓库中,构件通过POM(一种XML文件)来描述相关信息以及传递性依赖。Gradle 可以通过分析该文件获取获取所以依赖以及依赖的依赖和依赖的依赖的依赖,为了更加直观的表述,可以通过下面的输出结果了解。

+--- org.springframework:spring-web:4.3.4.RELEASE|    |    +--- org.springframework:spring-aop:4.3.4.RELEASE|    |    +--- org.springframework:spring-beans:4.3.4.RELEASE|    |    +--- org.springframework:spring-context:4.3.4.RELEASE|    |    \--- org.springframework:spring-core:4.3.4.RELEASE

可以看到,我们的项目依赖了spring-web,然而spirng-web却依赖了一众spring的全家桶,借助Gradle的传递性依赖特性,你无需再你的脚本中把这些依赖都声明一遍,你只需要简单的一行,Gradle便会帮你将传递性依赖一起下载下来。

// 下载包含该库在内的其他所依赖的所有库compile `org.springframework:spring-web:4.3.4.RELEASE`

传递依赖特性可以轻松地通过transitive参数进行开启或关闭,上面的示例中如果要忽略spring-web的传递性依赖可以采用指定 transitive = false 的方式来关闭依赖传递特性,也可以采用添加@jar的方式忽略该依赖的所有传递性依赖。

// 只下载该库,其他所依赖的所有库不下载compile("org.springframework:spring-web:4.3.4.RELEASE") {    transitive = false}
// 只下载该库,其他所依赖的所有库不下载compile `org.springframework:spring-web:4.3.4.RELEASE@jar`

或者采用@aar的方式关闭传递依赖

// 只下载该库,其他所依赖的所有库不下载compile 'io.reactivex.rxjava2:rxandroid:2.0.1@aar'// 在使用@aar的前提下还能下载其他依赖库,则需要添加transitive=true的条件compile ("io.reactivex.rxjava2:rxandroid::2.0.1@aar") {    transitive=true}

下面的语句,可以全局性的关闭依赖传递特性。

configurations.all {   transitive = false}

排除依赖

有些时候你可能需要排除一些传递性依赖中的某个模块,此时便不能靠单纯的关闭依赖传递特性来解决了。这时exclude就该登场了,如果说@jar彻底的解决了传递问题,那么exclude则是部分解决了传递问题。然而实际上exclude肯能还会用的频率更更频繁一些,比如下面几种情况。

  • 依赖冲突时,如果有两个依赖引用了相同jar包的不同版本时,默认情况下gradle会采用最新版本的jar包,此时可以通过排除选项来排除。
  • 运行期无需此模块的。
  • 无法正常获取到此传递依赖,远程仓库都不存在的。
  • 版权原因需要排除的。
  • 其他原因。

可以通过configuration配置或者在依赖声明时添加exclude的方式来排除指定的引用。

exclude可以接收group和module两个参数,这两个参数可以单独使用也可以搭配使用,其中module可以理解为对应GAV中的artifactId,也就是compile group: ‘org.gradle.test.classifiers’, name: ‘service’, version: ‘1.0’中的中间name部分。

configurations {    //编译期排除commons模块    compile.exclude module: 'commons'    //在整个构建过程中排除pkaq.tiger:share    all*.exclude group: 'pkaq.tiger', module: 'share'}// 去除某一个依赖库compile dependencies {    compile("pkaq.tiger:web:1.0") {        exclude module: 'share'    }       }

如果在configuration中定义一个exclude,那么所有单独设置的transitive dependency都会被去除。你可以只指定group的名字, 或只指定module的名字,或二者都指定

//将项目中的所有rxjava2引用都去除configurations {    all*.exclude group: 'io.reactivex.rxjava2', module: 'rxjava'}//或者这样configurations {    compile.exclude module: 'rxjava'}

使用强制版本

当然,有时候你可能仅仅是需要强制使用某个统一的依赖版本,而不是排除他们,那么此时force就该登场了。指定force = true属性可以冲突时优先使用该版本进行解决。

compile('org.hibernate:hibernate:3.1') {    force = true}

全局配置强制使用某个版本的依赖来解决依赖冲突中出现的依赖

configurations.all {   resolutionStrategy {       force 'org.hamcrest:hamcrest-core:1.3'   }}

使用动态版本

如果你想让你的工程始终采用最新依赖,那么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}

原文链接:[Gradle中文教程系列]-跟我学Gradle-5.3:依赖-管理依赖的版本(传递(transitive)\排除(exclude)\强制(force)\动态版本(+))

按构建目标定制依赖库

如果你想给productFlavors中的version2添加相应的依赖,只需要在它的名称后面加上Compile这样配置即可,例如:

//jsCompile files('libs/MiPush_SDK_Client_3_2_2.jar')version2Compile 'com.github.AlphaBoom:ClassifyView:0.5.2'

这里的构建目标可以是buildType也可以是productFlavors。

gradle dependencies中的->、 (*):

这里写图片描述

  • 固定版本: 唯一的依赖
  • 固定版本(* ): 还存在该库其他版本的依赖或者间接依赖,并且默认选择(*)所标注的版本。这里rxjava版本就是使用rxbinding里的2.0.2
  • 版本1->版本2(*): 还存在该库其他版本的依赖或者间接依赖,并且并且选择版本2。这里rxandroid版本就是使用2.0.1