Android Gradle传递依赖优先级高于声明依赖?是否符合预期?
问题背景
在build.gradle中声明了以下直接依赖:
implementation "androidx.recyclerview:recyclerview:1.1.0" implementation 'com.github.kirich1409:viewbindingpropertydelegate-noreflection:1.5.6'
其中viewbindingpropertydelegate-noreflection:1.5.6包含传递依赖:
implementation "androidx.recyclerview:recyclerview:1.2.1"
查看依赖树时发现直接声明的1.1.0版本被替换为1.2.1:
+--- androidx.recyclerview:recyclerview:1.1.0 -> 1.2.1
同时代码中出现了1.1.0之后新增的getBindingAdapterPosition方法,疑问点在于:
- 这是Gradle的正确行为吗?
- 如果代码依赖1.1.0独有的功能,该如何处理?
问题解答
1. 这是Gradle的正确行为
是的,这符合Gradle默认的依赖解析规则:当同一模块存在多个版本时,Gradle会自动选择版本号最高的那个,无论该版本来自直接依赖还是传递依赖。
在你的场景中,androidx.recyclerview:recyclerview存在1.1.0(直接依赖)和1.2.1(传递依赖)两个版本,1.2.1版本号更高,因此Gradle会自动将1.1.0替换为1.2.1,这是正常的依赖解析逻辑。
2. 若依赖1.1.0独有的功能的处理方案
如果你的代码必须依赖1.1.0版本的独有功能,可以通过以下方式强制Gradle使用指定版本:
方案一:给直接依赖添加force属性
在声明androidx.recyclerview:recyclerview依赖时,通过闭包设置force = true,强制Gradle忽略其他版本:
implementation("androidx.recyclerview:recyclerview:1.1.0") { force = true }
方案二:全局配置版本强制策略
在模块的build.gradle中添加全局依赖解析策略,强制指定该模块的版本:
configurations.all { resolutionStrategy { force "androidx.recyclerview:recyclerview:1.1.0" } }
注意:强制指定旧版本可能引发兼容性风险——比如
viewbindingpropertydelegate-noreflection:1.5.6是基于1.2.1版本开发的,使用1.1.0可能导致该库出现适配问题。因此建议优先评估是否可以升级代码适配1.2.1版本,仅在确有必要时再强制使用旧版本。
内容的提问来源于stack exchange,提问作者Goltsev Eugene

