假如项目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