Android Gradle重复依赖项的处理

假如项目app依赖了 LIB_A 和 LIB_B,而 LIB_A 又依赖了 LIB_C 和 LIB_D,LIB_B 也依赖于 LIB_C,假设都是用implementation的方式来依赖,那么最终构建完成到底将多少个依赖库打包进了apk里边?答案是4个,LIB_A ,LIB_B,LIB_C 和LIB_D。即使重复引用,Gradle最终也只会将一个依赖项打包到构建输出。

那么,如果两个LIB_C的版本不一样呢?Gradle默认会选择最高的那个版本。假如LIB_A引用的LIB_C 的版本是1.0.0,而LIB_B 引用的LIB_C 的版本是1.1.0,那么在构建输出中用的便是1.1.0的LIB_C的代码。

但是LIB_A当时自己在打包成lib的时候,用的却是依旧1.0.0的代码,那可能就有问题了。比如LIB_C中某个类在1.1.0中被删掉了,而LIB_A却用到了,那么这个app在运行时就有可能因为LIB_A找不到这个类而抛出运行时错误。

幸好,Gradle Plugin 提供了一个任务,可以用于分析项目的依赖树。这个命令是这样的:

gradlew app:dependencies

其中,app是模块的名称。比如我们看androidx.appcompat:appcompat这个依赖库,其中符号的含义:

  • x.x.x (*) 该依赖已经有了,将不再重复依赖。
  • x.x.x -> x.x.x 该依赖的版本被箭头所指的版本代替。
  • x.x.x -> x.x.x(*) 该依赖的版本被箭头所指的版本代替,并且该依赖已经有了,不再重复依赖。
+--- androidx.appcompat:appcompat:1.0.2
|    +--- androidx.annotation:annotation:1.0.0
|    +--- androidx.core:core:1.0.1
|    |    +--- androidx.annotation:annotation:1.0.0
|    |    +--- androidx.collection:collection:1.0.0
|    |    |    \--- androidx.annotation:annotation:1.0.0
|    |    +--- androidx.lifecycle:lifecycle-runtime:2.0.0
|    |    |    +--- androidx.lifecycle:lifecycle-common:2.0.0
|    |    |    |    \--- androidx.annotation:annotation:1.0.0
|    |    |    +--- androidx.arch.core:core-common:2.0.0
|    |    |    |    \--- androidx.annotation:annotation:1.0.0
|    |    |    \--- androidx.annotation:annotation:1.0.0
|    |    \--- androidx.versionedparcelable:versionedparcelable:1.0.0
|    |         +--- androidx.annotation:annotation:1.0.0
|    |         \--- androidx.collection:collection:1.0.0 (*)
|    +--- androidx.collection:collection:1.0.0 (*)
|    +--- androidx.cursoradapter:cursoradapter:1.0.0
|    |    \--- androidx.annotation:annotation:1.0.0
|    +--- androidx.legacy:legacy-support-core-utils:1.0.0
|    |    +--- androidx.annotation:annotation:1.0.0
|    |    +--- androidx.core:core:1.0.0 -> 1.0.1 (*)
|    |    +--- androidx.documentfile:documentfile:1.0.0
|    |    |    \--- androidx.annotation:annotation:1.0.0
|    |    +--- androidx.loader:loader:1.0.0
|    |    |    +--- androidx.annotation:annotation:1.0.0
|    |    |    +--- androidx.core:core:1.0.0 -> 1.0.1 (*)
|    |    |    +--- androidx.lifecycle:lifecycle-livedata:2.0.0
|    |    |    |    +--- androidx.arch.core:core-runtime:2.0.0
|    |    |    |    |    +--- androidx.annotation:annotation:1.0.0
|    |    |    |    |    \--- androidx.arch.core:core-common:2.0.0 (*)
|    |    |    |    +--- androidx.lifecycle:lifecycle-livedata-core:2.0.0
|    |    |    |    |    +--- androidx.lifecycle:lifecycle-common:2.0.0 (*)
|    |    |    |    |    +--- androidx.arch.core:core-common:2.0.0 (*)
|    |    |    |    |    \--- androidx.arch.core:core-runtime:2.0.0 (*)
|    |    |    |    \--- androidx.arch.core:core-common:2.0.0 (*)
|    |    |    \--- androidx.lifecycle:lifecycle-viewmodel:2.0.0
|    |    |         \--- androidx.annotation:annotation:1.0.0
|    |    +--- androidx.localbroadcastmanager:localbroadcastmanager:1.0.0
|    |    |    \--- androidx.annotation:annotation:1.0.0
|    |    \--- androidx.print:print:1.0.0
|    |         \--- androidx.annotation:annotation:1.0.0
|    +--- androidx.fragment:fragment:1.0.0
|    |    +--- androidx.core:core:1.0.0 -> 1.0.1 (*)
|    |    +--- androidx.legacy:legacy-support-core-ui:1.0.0
|    |    |    +--- androidx.annotation:annotation:1.0.0
|    |    |    +--- androidx.core:core:1.0.0 -> 1.0.1 (*)
|    |    |    +--- androidx.legacy:legacy-support-core-utils:1.0.0 (*)
|    |    |    +--- androidx.customview:customview:1.0.0
|    |    |    |    +--- androidx.annotation:annotation:1.0.0
|    |    |    |    \--- androidx.core:core:1.0.0 -> 1.0.1 (*)
|    |    |    +--- androidx.viewpager:viewpager:1.0.0
|    |    |    |    +--- androidx.annotation:annotation:1.0.0
|    |    |    |    +--- androidx.core:core:1.0.0 -> 1.0.1 (*)
|    |    |    |    \--- androidx.customview:customview:1.0.0 (*)
|    |    |    +--- androidx.coordinatorlayout:coordinatorlayout:1.0.0
|    |    |    |    +--- androidx.annotation:annotation:1.0.0
|    |    |    |    +--- androidx.core:core:1.0.0 -> 1.0.1 (*)
|    |    |    |    \--- androidx.customview:customview:1.0.0 (*)
|    |    |    +--- androidx.drawerlayout:drawerlayout:1.0.0
|    |    |    |    +--- androidx.annotation:annotation:1.0.0
|    |    |    |    +--- androidx.core:core:1.0.0 -> 1.0.1 (*)
|    |    |    |    \--- androidx.customview:customview:1.0.0 (*)
|    |    |    +--- androidx.slidingpanelayout:slidingpanelayout:1.0.0
|    |    |    |    +--- androidx.annotation:annotation:1.0.0
|    |    |    |    +--- androidx.core:core:1.0.0 -> 1.0.1 (*)
|    |    |    |    \--- androidx.customview:customview:1.0.0 (*)
|    |    |    +--- androidx.interpolator:interpolator:1.0.0
|    |    |    |    \--- androidx.annotation:annotation:1.0.0
|    |    |    +--- androidx.swiperefreshlayout:swiperefreshlayout:1.0.0
|    |    |    |    +--- androidx.annotation:annotation:1.0.0
|    |    |    |    +--- androidx.core:core:1.0.0 -> 1.0.1 (*)
|    |    |    |    \--- androidx.interpolator:interpolator:1.0.0 (*)
|    |    |    +--- androidx.asynclayoutinflater:asynclayoutinflater:1.0.0
|    |    |    |    +--- androidx.annotation:annotation:1.0.0
|    |    |    |    \--- androidx.core:core:1.0.0 -> 1.0.1 (*)
|    |    |    \--- androidx.cursoradapter:cursoradapter:1.0.0 (*)
|    |    +--- androidx.legacy:legacy-support-core-utils:1.0.0 (*)
|    |    +--- androidx.annotation:annotation:1.0.0
|    |    +--- androidx.loader:loader:1.0.0 (*)
|    |    \--- androidx.lifecycle:lifecycle-viewmodel:2.0.0 (*)
|    +--- androidx.vectordrawable:vectordrawable:1.0.1
|    |    +--- androidx.annotation:annotation:1.0.0
|    |    \--- androidx.core:core:1.0.0 -> 1.0.1 (*)
|    \--- androidx.vectordrawable:vectordrawable-animated:1.0.0
|         +--- androidx.vectordrawable:vectordrawable:1.0.0 -> 1.0.1 (*)
|         \--- androidx.legacy:legacy-support-core-ui:1.0.0 (*)

参考:

# 解决 Android Gradle 依赖的各种版本问题

# Using gradle to find dependency tree

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

推荐阅读更多精彩内容

  • 1. 关于诊断X线机准直器的作用,错误的是()。 (6.0 分) A. 显示照射野 B. 显示中心线 C. 屏蔽多...
    我们村我最帅阅读 10,257评论 0 5
  • 在C语言中,五种基本数据类型存储空间长度的排列顺序是: A)char B)char=int<=float C)ch...
    夏天再来阅读 3,320评论 0 2
  • 1. 下列叙述错误的是()。 (2.0 分) A. 质量管理包括QA和QC一切活动的全部过程 B. 影像质量是指对...
    我们村我最帅阅读 3,766评论 0 8
  • 1.埋点是做什么的 2.如何进行埋点 3.埋点方案的设计 近期常被问到这个问题,我担心我的答案会将一些天真烂漫的孩...
    lxg阅读 2,012评论 0 1
  • 腊月二十七表姐女儿出嫁了,我问表哥:表姐哭了吗?他说表姐哭的心酸。这是传统的哭嫁。 时间过得好快,一转眼表姐女儿都...
    文馨_阅读 1,399评论 4 6