前言
当我们遇到gradle的版本依赖冲突时,一般可以通过force语句来处理:
1 | resolutionStrategy { |
当如果我们不使用force语句时,原本的gradle版本冲突时如何处理的呢?
版本冲突处理
当我们添加了gradle的源码依赖后:
1 | implementation gradleApi() |
我们可以找到下面的枚举类:
1 | /** |
其中:
- strict:严格模式,通过 failOnVersionConflict() 来设置,表示如果存在依赖冲突则失败
- latest:选择最新的,默认选项
- preferProjectModules:没用过,官方说明是 prefer modules that are part of this build (multi-project or composite build) over external modules
一般而言,我们都是默认选择最新的版本
但由于依赖库的版本号是字符串,而非数字,那么gradle默认的实现是如何判断哪个版本是最新呢?
gradle最新版本判断代码
枚举latest对应的版本处理类是 LatestModuleConflictResolver
他的构造函数中需要传入处理版本冲突的版本对比器,默认实现代码如下:
1 | /** |
其中StaticVersionComparator代码如下:
1 | /** |
其中使用到的Version类的解析数据代码如下:
1 | public class VersionParser implements Transformer<Version, String> { |
结论
由上面的代码可知:
- 我们表示版本的字符串,首先会根据 ._-+ 分隔符分为多个部分,每个部分中,只会存在数字或者非数字的字符串
- 对比版本新旧时,其实是对版本的每个部分进行对比
- 同一部分中,数字的部分版本大于非数字的字符串,如果同为数字,则比较大小
- 同为字符串的情况下,查看是否特殊字符串,dev表示最低级别版本,低于普通字符串,rc高于普通字符串,release更高,最高的级别是final
- 同为普通字符串的情况下,通过string的compare方法来进行对比
- 如果上面的对比情况均相等,则判断最后较长的版本中,最后一部分是否为数字,为数字则较长的版本号为最新