如何防止 Gradle 将库的依赖版本更改为更高版本,因为另一个库需要它作为传递依赖项?

joe*_*joe 7 android gradle okhttp

语境

我正在尝试使用网络插件将Flipper 调试工具包含到我的应用程序中。为了使它有用,我需要在我的 HTTP 模块中添加一个 Flipper Network 拦截器,它提供一个 OkHttp 客户端供我的应用程序使用。我只在调试配置中包含 Flipper 库。我在我的 http 模块中包含了 Flipper deps,如下所示:

dependencies {
[...]
    debugImplementation dep('com.facebook.flipper:flipper')
    debugImplementation dep('com.facebook.flipper:flipper-network-plugin')
}

Run Code Online (Sandbox Code Playgroud)

问题

我面临的问题是Flipper 传递依赖okhttp:3.14.1',并且我们的应用程序支持高达 API 级别 16 的客户端。现在的问题是,在 API 21 (Lolipop) 以下,我无法使用 3.12.x 以上的任何版本的 okhttp。

正因为如此,其他依赖OkHttp的东西,开始使用OkHttp8.12.x以上的版本,这使得HTTP的初始化中断。

11-08 13:48:28.394 E/AndroidRuntime: FATAL EXCEPTION: main
    java.lang.NoClassDefFoundError: java.util.Objects
        at okhttp3.CertificatePinner.withCertificateChainCleaner(CertificatePinner.java:231)
        at okhttp3.OkHttpClient.<init>(OkHttpClient.java:238)
        at okhttp3.OkHttpClient.<init>(OkHttpClient.java:202)
Run Code Online (Sandbox Code Playgroud)

查看依赖关系树,在我看来,因为 Flipper 需要 OkHttp 版本 3.14.1,所以我的应用程序中在调试配置中需要 OkHttp 客户端的其他部分也使用 3.14.1 而不是 3.12.3:

debugAndroidTest
[...]
+--- project :libs:http-retrofit
|    +--- project :libs:http (*)
|    +--- com.squareup.okhttp3:okhttp:3.12.3 -> 3.14.1 (*)
|    +--- javax.inject:javax.inject:1
|    +--- com.squareup.retrofit2:retrofit:2.5.0
|    |    \--- com.squareup.okhttp3:okhttp:3.12.0 -> 3.14.1 (*)

Run Code Online (Sandbox Code Playgroud)

如何让 Gradle 不更改其他地方 OkHTTP 的依赖版本?

编辑澄清:

基本上我希望所有依赖于 OkHttp 的 Gradle 依赖项都使用版本 3.12.3(无论 Android API 版本如何),除了 Flipper,我只在调试版本中包含它,如果确实需要,它应该能够拥有版本 3.14.1到。

小智 2

来自依赖约束gradle 指南:

依赖项约束允许您定义构建脚本中声明的依赖项和传递依赖项的版本或版本范围。

以及声明丰富版本指南:

严格 任何与此版本符号不匹配的版本都将被排除。这是最强版本宣言。对于已声明的依赖项,严格可以降级版本。当存在传递依赖时,如果无法选择此子句可接受的版本,则会导致依赖解析失败。有关详细信息,请参阅覆盖依赖项版本。该术语支持动态版本。

定义后,将覆盖先前的 require 声明并清除先前的拒绝。

所以把这些放在一起,我认为你应该能够做这样的事情:

dependencies {
[...]
    debugImplementation dep('com.facebook.flipper:flipper')
    debugImplementation dep('com.facebook.flipper:flipper-network-plugin')

    constraints {
        debugImplementation dep('com.squareup.okhttp3:okhttp') {
            version {
                strictly '3.12.3'
            }
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,如果其中一个依赖项无法与 3.12.3 版本一起工作,那么它将无法解决约束。