Gradle依赖

原文:Gradle dependencies

译者:个别地方翻译可能不是很好,反复读了几遍,内容对自己帮助还是挺大的。

前段时间我们谈了Gradle,今天我们将会讨论Gradle的依赖管理,对于Android来说是一个伟大的功能。

gradle
gradle

使用Gradle你可以用类似Maven的方式轻松管理一些依赖像Play Services,support libraries,或者其他库。既然这样,那么你可以反问自己一些关于管理依赖的问题:

  • 当一个项目中的2个依赖同时依赖某个依赖,而它们的各自依赖的版本号有冲突的时候,怎么进行管理?(a,b同时依赖c ,a依赖c1.1,b依赖c2.1)
  • 什么是传递依赖解析?
  • 可选依赖的作用?

本文会用一些我们熟悉的例子清晰得来解决这些问题。

演示项目

本文讨论的例子都放在了Github上面,你可以clone下来自己尝试一下。

怎么添加依赖

例子

Calligraphy是一个知名的管理字体的android库,为了用它,你需要在项目build.gradle添加它作为项目的一个依赖:

compile 'uk.co.chrisjenx:calligraphy:2.1.0'

这是一个很典型用来添加依赖的例子,但是它自身有其他依赖呢?为了列出你项目中所有的依赖(包含依赖的子依赖)你可以用下面这个命令:

./gradlew dependencies app:dependencies

这个命令会列出app module每一个configuration的依赖,为了减少输出内容我们只对compile configuration感兴趣。

./gradlew dependencies app:dependencies --configuration compile

我们获取到下面的结果(译者:自己可以查看下自己控制台输出更清晰):

compile - Classpath for compiling the main sources.
--- uk.co.chrisjenx:calligraphy:2.1.0
\--- com.android.support:appcompat-v7:22.1.1
\ --- com.android.support:support-v4:22.1.1
\  --- com.android.support:support-annotations:22.1.1

我们可以看到Calligraphy依赖appcompat-v7,而v7本身又依赖appcompat-v4,v4反过来又依赖support-annotations,这些依赖不用我们添加默认就解决好了,它们被传递解决了。

可传递性依赖

例子

要是我们的app module已经使用了appcompat-v7,但是,是更高版本23.1.1,那么最终app使用的是哪个版本的appcompat-v7,是Calligraphy依赖的22.1.1吗?让我们运行命令再来分析下:

compile - Classpath for compiling the main sources.
+--- uk.co.chrisjenx:calligraphy:2.1.0
|    --- com.android.support:appcompat-v7:22.1.1 -> 23.1.1
|         --- com.android.support:support-v4:23.1.1
|              --- com.android.support:support-annotations:23.1.1
--- com.android.support:appcompat-v7:23.1.1 (*)

calligraphy依赖的appcompat-v7:22.1.1已经变成了appcompat-v7:23.1.1,默认,依赖解析是可传递的,也就是以递归的方式解析所有依赖(包括依赖的依赖),如果有冲突则取高的版本号。这就是为什么support-v4和support-annotations会自动引入到我的app module(我们没有必要在build.gradle进行添加它们了)

依赖解析策略

例子

我们可以添加下面的代码块到我们的build.gradle中用来通知我们是否项目的同一个依赖有2个不同版本:

configurations.all {
  resolutionStrategy {
    failOnVersionConflict()
  }
}

再build时上面的代码会触发错误,强制我们手动解决版本冲突。默认情况下,Gradle用它自己的依赖解析策略,当发生版本冲突时,它会使用高版本号,你也可以定义自己的解析策略,类似上面这个(文档)

过滤依赖

例子

此外,我们可以直接配置Gradle怎样建立依赖,例如,如果查看simple-xml库,依赖分析结果如下:

compile - Classpath for compiling the main sources.
--- org.simpleframework:simple-xml:2.7.1
+--- stax:stax-api:1.0.1
+--- stax:stax:1.2.0
|    \--- stax:stax-api:1.0.1
\--- xpp3:xpp3:1.1.3.3

配置是无法通过编译,因为下面的原因:

  • xpp3本身就直接被包含在Android framework中,我们不能包含同包名,同类名的另外一个版本的xpp3
  • stax用的是android framework受保护的包名(java.xml.*),然而不用担忧simple-xml可以工作在Android上因为它的依赖stax是可选的
    (stax的可用性是在运行时被检查

但是我们需要修改build.gradle以便编译期间忽略stax(顺便说一下,编译系统足够聪明会自动忽略xpp3,只是会显示一个警告),我们可以用下面的语法排除stax

compile('org.simpleframework:simple-xml:2.7.1'){
  exclude module: 'stax'
  exclude module: 'stax-api'
  exclude module: 'xpp3' // optional
}

相应的DSL文档请查看这里

给library开发者

有了前面的例子我们可以看到没有stax,simple-xml也可以工作,如果我们看一下它的pom.xml,我们会发现stat不是一个可选依赖。但是它却可以定义为一个可选依赖。让我们细想一下:一个library L依赖一个可选的library O,L传递依赖解析的时候不会包含O依赖。

在simple-xml的例子中,如果stax和xpp3是可选依赖,我们就可以直接像下面声明simple-xml依赖:

compile 'org.simpleframework:simple-xml:2.7.1'

实际上,Retrofit1就是这种情况,OKHttp是一个可选的依赖。那么在运行时,如果OkHttp可用,Retrofit会使用OkHttp作为默认的http client,否则将使用Retrofit用到的平台提供的默认http client,我们还注意到Retrofit 1没有使用Gradle而是Maven。我们可以解释这个选择是因为声明可选依赖还没有被Gradle原生支持。但是目前有一些解决方案可以让你实现:

总结

通过Gradle进行依赖管理是非常有帮助的。清晰的理解怎么配置这些依赖可以让你以一种有意义的方式管理依赖关系在android项目周期的演变。
不仅如此,一个非常精确的库依赖配置对开发人员帮助很大,可以很容易地包括在其他项目,如Retrofit.

特别感谢Adrien Couque给予我的帮助。

相关资源

Gradle的高级技巧

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容