【安卓学习之常见问题】gradle依赖冲突

█ 【安卓学习之常见问题】gradle依赖冲突


█ 系列文章目录

提示:这里是收集了和文件分享有关的文章

█ 文章目录


█ 读前说明

  • 本文通过学习别人写demo,学习一些课件,参考一些博客,’学习相关知识,如果涉及侵权请告知
  • 本文只简单罗列相关的代码实现过程
  • 涉及到的逻辑以及说明也只是简单介绍,主要当做笔记,了解过程而已    

█ 问题

  • 在okhttp3/HttpUrl类内部没有虚方法getHttpUrlChecked; 或其超类(‘okhttp3.internal.Internal’ 的声明出现在 /data/app/com.xxx.xxx-1/base.apk 中)
# AsyncTask #9(4586)

java.lang.NoSuchMethodError

No virtual method getHttpUrlChecked(Ljava/lang/String;)Lokhttp3/HttpUrl; in class Lokhttp3/internal/Internal; or its super classes (declaration of 'okhttp3.internal.Internal' appears in /data/app/com.xxx.xxx-1/base.apk)
java.lang.RuntimeException:An error occurred while executing doInBackground()
android.os.AsyncTask$3.done(AsyncTask.java:325)
......
Caused by:
java.lang.NoSuchMethodError:No virtual method getHttpUrlChecked(Ljava/lang/String;)Lokhttp3/HttpUrl; in class Lokhttp3/internal/Internal; or its super classes (declaration of 'okhttp3.internal.Internal' appears in /data/app/com.xxx.xxx-1/base.apk)
okhttp3.internal.huc.OkHttpURLConnection.buildCall(OkHttpURLConnection.java:375)
okhttp3.internal.huc.OkHttpURLConnection.connect(OkHttpURLConnection.java:123)
okhttp3.internal.huc.DelegatingHttpsURLConnection.connect(DelegatingHttpsURLConnection.java:90)
okhttp3.internal.huc.OkHttpsURLConnection.connect(OkHttpsURLConnection.java:26)

在这里插入图片描述

  • 出错的代码
    public static int fetchReferenceTileUrl(Context context){
        final String referenceUrl = "https://a.tiles.mapbox.com/v4/mapId/0/0/0@2x.png?access_token=accessToken";
        HttpURLConnection conn = null;
        try{
            conn = NetworkUtilsPlus.getHttpURLConnection(new URL(referenceUrl));
            Timber.d("Download reference mapbox tile @ %s", referenceUrl);
            conn.setConnectTimeout(10000);
            conn.connect();//  =============================================奔溃报错
            int result = conn.getResponseCode();
            return result;
        }catch(IOException e){
            Timber.e(e, "Error while retrieving mapbox reference tile.");
        }
        finally{
            if(conn != null)
                conn.disconnect();
        }
            return -1;
    }
    public static HttpURLConnection getHttpURLConnection(final URL url, final Cache cache, final SSLSocketFactory sslSocketFactory) 				{
        OkHttpClient.Builder builder = new OkHttpClient.Builder();

        if (cache != null) {
            builder.cache(cache);
        }
        if (sslSocketFactory != null) {
            builder.sslSocketFactory(sslSocketFactory);
        }
        HttpURLConnection connection = new OkUrlFactory(builder.build()).open(url);
        connection.setRequestProperty("User-Agent", MapboxUtils.getUserAgent());
        return connection;
    }
  • 找下 okhttp3/HttpUrl类和okhttp3/internal/Internal类,没有getHttpUrlChecked方法

在这里插入图片描述

在这里插入图片描述

█ 问题分析1(查看报错位置)

  • OkUrlFactory 废弃,但是能编译通过
 HttpURLConnection connection = new OkUrlFactory(builder.build()).open(url);
 /**
 * @deprecated OkHttp will be dropping its ability to be used with {@link HttpURLConnection} in an
 * upcoming release. Applications that need this should either downgrade to the system's built-in
 * {@link HttpURLConnection} or upgrade to OkHttp's Request/Response API.
 */

在这里插入图片描述

>>>>OkUrlFactory属于com.squareup.okhttp3:okhttp-urlconnection:3.4.1中的,将要被废弃

  • 上一步生成的connection 实际上就是类OkHttpsURLConnection
public final class OkUrlFactory implements URLStreamHandlerFactory, Cloneable {
  HttpURLConnection open(URL url, Proxy proxy) {
    String protocol = url.getProtocol();
    OkHttpClient copy = client.newBuilder()
        .proxy(proxy)
        .build();

    if (protocol.equals("http")) return new OkHttpURLConnection(url, copy, urlFilter);
    if (protocol.equals("https")) return new OkHttpsURLConnection(url, copy, urlFilter);
    throw new IllegalArgumentException("Unexpected protocol: " + protocol);
  }
}

>>>>也就是说使用了3.4.1的OkHttpsURLConnection,去执行.connect()

  • OkHttpsURLConnection.connect()相当于OkHttpURLConnection.connect()
public final class OkHttpsURLConnection extends DelegatingHttpsURLConnection {
  private final OkHttpURLConnection delegate;

  public OkHttpsURLConnection(URL url, OkHttpClient client, URLFilter filter) {
    this(new OkHttpURLConnection(url, client, filter));
  }

  public OkHttpsURLConnection(OkHttpURLConnection delegate) {
    super(delegate);
    this.delegate = delegate;
  }
}
abstract class DelegatingHttpsURLConnection extends HttpsURLConnection {
  private final HttpURLConnection delegate;// OkHttpURLConnection 

  public DelegatingHttpsURLConnection(HttpURLConnection delegate) {
    super(delegate.getURL());
    this.delegate = delegate;// OkHttpURLConnection 
  }
  @Override public void connect() throws IOException {
    connected = true;
    delegate.connect();// OkHttpURLConnection 
  }
}
  • OkHttpURLConnection
 @Override public void connect() throws IOException {
    if (executed) return;

    Call call = buildCall();
	。。。。。。
  }

  private Call buildCall() throws IOException {
	。。。。。。
	// 这里的 Internal.instance 是OkHttpClient中初始化,okhttp:3.14.7,没有getHttpUrlChecked方法
    Request request = new Request.Builder()
        .url(Internal.instance.getHttpUrlChecked(getURL().toString()))//  报错,找不到getHttpUrlChecked
        .headers(requestHeaders.build())
        .method(method, requestBody)
        .build();
	。。。。。。
    return call = clientBuilder.build().newCall(request);
  }

>>>>3.4.1的OkHttpURLConnection.connect(),中的Internal.instance.getHttpUrlChecked(),去调用了3.14.7的Internal.instance.getHttpUrlChecked(),而3.14.7中已经删除该方法了

Internal.instance初始化, okhttp:3.14.7版本没有getHttpUrlChecked:✘✘✘✘✘

public class OkHttpClient implements Cloneable, Call.Factory, WebSocket.Factory {
  static {
    Internal.instance = new Internal() {
      。。。。。。
      @Override
      public void apply(ConnectionSpec tlsConfiguration, SSLSocket sslSocket, boolean isFallback) {
        tlsConfiguration.apply(sslSocket, isFallback);
      }
      @Override public @Nullable Exchange exchange(Response response) {
        return response.exchange;
      }
    };
  }
}

Internal.instance初始化,okhttp:3.4.1版本有getHttpUrlChecked:✔✔✔✔✔

public class OkHttpClient implements Cloneable, Call.Factory {
  static {
    Internal.instance = new Internal() {
     。。。。。。
      @Override
      public void apply(ConnectionSpec tlsConfiguration, SSLSocket sslSocket, boolean isFallback) {
        tlsConfiguration.apply(sslSocket, isFallback);
      }
     //=====================调用这个方法
      @Override public HttpUrl getHttpUrlChecked(String url)
          throws MalformedURLException, UnknownHostException {
        return HttpUrl.getChecked(url);
      }
    };
  }
}
  • 解决方法

解决方法1:不能再用OkUrlFactory废弃的方法,版本不一致,接口调用找不到对应的方法,修改如下:

    public static HttpURLConnection getHttpURLConnection(final URL url) throws IOException {
        HttpURLConnection connection =(HttpURLConnection)(url.openConnection());// new OkUrlFactory(builder.build()).open(url);
        connection.setRequestProperty("User-Agent", MapboxUtils.getUserAgent());
        return connection;
    }

解决方法2:在app下build.gradle中强制使用低版本的okhttp:3.4.1,不推荐

apply plugin: 'com.android.application'
android {
    compileSdkVersion android_build_sdk_version
    buildToolsVersion android_build_tools_version
    defaultConfig {
        minSdkVersion android_build_min_sdk_version
        targetSdkVersion android_build_target_sdk_version
		。。。。。。
    }
	。。。。。。
}

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
     //okhttp
    implementation 'com.squareup.okhttp3:okhttp:3.4.1'
    implementation 'com.squareup.okhttp3:okhttp-urlconnection:3.4.1'
    implementation  'com.squareup.okhttp3:logging-interceptor:3.9.0'
    //retrofit
    implementation 'com.squareup.retrofit2:retrofit:2.7.2'
    implementation 'com.squareup.retrofit2:converter-gson:2.7.2'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.7.2'
    implementation 'com.squareup.retrofit2:converter-moshi:2.4.0'

    implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'   
}

configurations.all {
    resolutionStrategy {
        force 'com.squareup.okhttp3:okhttp:3.4.1'// =====新增
    }
}

  • okhttp版本修改记录

2015 年 12 月 13 日(最后提交日期),3.0版本之前版本,包名修改为 okhttp:
parent-2.7.5/okhttp/src/main/java/com/squareup/okhttp/internal/Internal.java

2016 年 1 月 2 日(最后提交日期),3.0版本后,包名修改为 okhttp3
parent-3.0.0-RC1/okhttp/src/main/java/okhttp3/internal/Internal.java

2017 年 3 月 6 日(最后提交日期),3.10是最后一个版本,带有getHttpUrlChecked方法
parent-3.10.0/okhttp/src/main/java/okhttp3/internal/Internal.java

2018 年 7 月 6 日(最后提交日期),3.11版本后,就删除了getHttpUrlChecked方法

parent-3.11.0/okhttp/src/main/java/okhttp3/internal/Internal.java

█ 问题分析2(dependencies依赖关系)

  • 运行终端中的执行 gradlew app:dependencies 查看依赖关系
错误: 找不到或无法加载主类 org.gradle.wrapper.GradleWrapperMain

在这里插入图片描述
在这里插入图片描述

  • 很多都是说,缺少gradle文件夹,可惜我是正常,都能正常编译运行的项目:
    在这里插入图片描述

  • 其实在输入【智能命令执行 Smart commands execution】都有文字提示,按 Ctrl+Enter 就可以执行
    在这里插入图片描述

Smart commands execution: Highlighted commands can be interpreted and executed by the IDE in a smart way. // Press Ctrl+Enter to try this, or Enter to run the command in the console as usual. // You can turn this behavior on/off in Preferences | Tools | Terminal. Got it! (moments ago)

在这里插入图片描述

XXXDebugAndroidTestCompileClasspath - Compile classpath for compilation 'XXXDebugAndroidTest' (target  (androidJvm)).
+--- com.tencent.bugly:crashreport:latest.release -> 4.1.9
+--- project :baseLib
|    +--- project :MyLib1
|    |    +--- androidx.core:core-ktx:1.6.0 (*)
|    |    +--- androidx.appcompat:appcompat:1.3.1 (*)
|    |    +--- com.google.android.material:material:1.4.0 (*)
|    +--- org.greenrobot:eventbus:3.1.1
|    +--- com.squareup.okhttp3:okhttp:3.4.1 -> 3.14.7
|    |    \--- com.squareup.okio:okio:1.17.2 -> 3.0.0-alpha.4
|    |         +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.20 -> 1.5.30 (*)
|    |         \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.4.20 -> 1.6.0
|    +--- com.squareup.okhttp3:okhttp-urlconnection:3.4.1
|    |    \--- com.squareup.okhttp3:okhttp:3.4.1 -> 3.14.7 (*)
|    +--- com.squareup.okhttp3:logging-interceptor:3.9.0
|    |    \--- com.squareup.okhttp3:okhttp:3.9.0 -> 3.14.7 (*)
|    +--- com.squareup.retrofit2:retrofit:2.7.2
|    |    \--- com.squareup.okhttp3:okhttp:3.14.7 (*)
|    +--- com.squareup.retrofit2:converter-gson:2.7.2
|    |    +--- com.squareup.retrofit2:retrofit:2.7.2 (*)
|    |    \--- com.google.code.gson:gson:2.8.5
|    +--- com.squareup.retrofit2:adapter-rxjava2:2.7.2
|    |    +--- com.squareup.retrofit2:retrofit:2.7.2 (*)
|    |    +--- io.reactivex.rxjava2:rxjava:2.0.0 -> 2.2.0
|    |    |    \--- org.reactivestreams:reactive-streams:1.0.2 -> 1.0.3
|    |    \--- org.reactivestreams:reactive-streams:1.0.3
|    +--- com.squareup.retrofit2:converter-moshi:2.4.0
|    |    +--- com.squareup.retrofit2:retrofit:2.4.0 -> 2.7.2 (*)
|    |    \--- com.squareup.moshi:moshi:1.5.0
|    |         \--- com.squareup.okio:okio:1.13.0 -> 3.0.0-alpha.4 (*)
|    +--- io.reactivex.rxjava2:rxandroid:2.1.0
|    |    \--- io.reactivex.rxjava2:rxjava:2.2.0 (*)
+--- project :MyLib2
|    +--- com.jakewharton.timber:timber:3.1.0
|    +--- project :MyLib2Child
|    |    \--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.30 (*)
|    +--- io.reactivex.rxjava2:rxandroid:2.1.0 (*)
+--- com.google.android.gms:play-services-maps:17.0.0
|    +--- androidx.fragment:fragment:1.0.0 -> 1.3.6 (*)
|    +--- com.google.android.gms:play-services-base:17.0.0 (*)
|    \--- com.google.android.gms:play-services-basement:17.0.0 (*)
+--- project :MyLib3
|    \--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.30 (*)
+--- com.squareup.okhttp3:okhttp:{strictly 3.14.7} -> 3.14.7 (c)
+--- com.squareup.okhttp3:okhttp-urlconnection:{strictly 3.4.1} -> 3.4.1 (c)
+--- com.squareup.okhttp3:logging-interceptor:{strictly 3.9.0} -> 3.9.0 (c)
+--- com.squareup.retrofit2:retrofit:{strictly 2.7.2} -> 2.7.2 (c)
+--- com.squareup.retrofit2:converter-gson:{strictly 2.7.2} -> 2.7.2 (c)
+--- com.squareup.retrofit2:adapter-rxjava2:{strictly 2.7.2} -> 2.7.2 (c)
+--- com.squareup.retrofit2:converter-moshi:{strictly 2.4.0} -> 2.4.0 (c)
+--- io.reactivex.rxjava2:rxandroid:{strictly 2.1.0} -> 2.1.0 (c)
+--- com.google.android.gms:play-services-location:{strictly 17.0.0} -> 17.0.0 (c)
+--- com.google.android.gms:play-services-base:{strictly 17.0.0} -> 17.0.0 (c)
+--- com.google.android.gms:play-services-basement:{strictly 17.0.0} -> 17.0.0 (c)
+--- com.squareup.okio:okio:{strictly 3.0.0-alpha.4} -> 3.0.0-alpha.4 (c)
+--- com.squareup.moshi:moshi:{strictly 1.5.0} -> 1.5.0 (c)
+--- com.google.android.gms:play-services-places-placereport:{strictly 17.0.0} -> 17.0.0 (c)
\--- com.google.android.gms:play-services-tasks:{strictly 17.0.0} -> 17.0.0 (c)


  • okhttp3的相关依赖
+--- project :baseLib
|    +--- org.greenrobot:eventbus:3.1.1
|    +--- com.squareup.okhttp3:okhttp:3.4.1 -> 3.14.7
|    |    \--- com.squareup.okio:okio:1.17.2 -> 3.0.0-alpha.4
|    +--- com.squareup.okhttp3:okhttp-urlconnection:3.4.1
|    |    \--- com.squareup.okhttp3:okhttp:3.4.1 -> 3.14.7 (*)
|    +--- com.squareup.okhttp3:logging-interceptor:3.9.0
|    |    \--- com.squareup.okhttp3:okhttp:3.9.0 -> 3.14.7 (*)
|    +--- com.squareup.retrofit2:retrofit:2.7.2
|    |    \--- com.squareup.okhttp3:okhttp:3.14.7 (*)
+--- com.squareup.okhttp3:okhttp:{strictly 3.14.7} -> 3.14.7 (c)
+--- com.squareup.okhttp3:okhttp-urlconnection:{strictly 3.4.1} -> 3.4.1 (c)
+--- com.squareup.okhttp3:logging-interceptor:{strictly 3.9.0} -> 3.9.0 (c)

>>>>代码里面只有baseLib中build.gradle有声明okhttp3

    //okhttp
    api 'com.squareup.okhttp3:okhttp:3.4.1'
    api 'com.squareup.okhttp3:okhttp-urlconnection:3.4.1'
    api 'com.squareup.okhttp3:logging-interceptor:3.9.0'
    //retrofit
    api 'com.squareup.retrofit2:retrofit:2.7.2'
    api 'com.squareup.retrofit2:converter-gson:2.7.2'
    api 'com.squareup.retrofit2:adapter-rxjava2:2.7.2'
    api 'com.squareup.retrofit2:converter-moshi:2.4.0'

    api 'io.reactivex.rxjava2:rxandroid:2.1.0'

>>>>虽然引用的是3.4.1,但是 logging-interceptor 将他提升到 3.9.0,retrofit 将他提升到 3.14.7

█ 依赖正常的解决方法

  • Duplicate class android.xx.xx:可能就是两个库导入了重复的类
  • exclude关键字
    implementation ('com.xxx.xxx.xx:xx:1.0.0'){
        exclude group: "com.xxxx.xxxx"
    }
implementation('androidx.constraintlayout:constraintlayout:1.1.3') {
    exclude group: 'androidx.constraintlayout', module: 'constraintlayout-solver'
}
  • configuration配置
//定义配置名称
configurations {
    //自定义配置名称
    abc {
        println 'abc'
    }
    //第二种方式解决冲突
    configuration {
        all*.exclude module: 'annotation'
    }
    //第三种方式解决冲突,强制指定
    all {
        resolutionStrategy {
            force 'androidx.fragment:fragment:1.0.0'
        }
    }
}

>>>>或者 将外面的版本设置和他一致

  • 这里直接采用

█ okhttp3的相关依赖

  • okhttp3的相关依赖
    api 'com.squareup.okhttp3:okhttp:3.4.1'
    api 'com.squareup.okhttp3:okhttp-urlconnection:3.4.1'
    api 'com.squareup.okhttp3:logging-interceptor:3.9.0'
  • 将其他相关依赖隐藏下,看看都依赖了哪些
    在这里插入图片描述

>>>>okhttp的版本怎么会不一样?

implementation "com.squareup.okio:okio:1.9.0"

>>>>上面显示的明明是1.13.0

implementation "com.squareup.okhttp3:okhttp:3.4.1"
implementation "org.codehaus.mojo:animal-sniffer-annotations:1.11"

>>>>上面显示的明明是3.9.0,看了是最后一个的版本更高了

在这里插入图片描述

implementation "com.squareup.okhttp3:okhttp:3.9.0"
implementation "com.squareup.okio:okio:1.13.0"

>>>>这样综合下,就可以得出最终的依赖
在这里插入图片描述
在这里插入图片描述

█ Pictureselector

  • 最早是这样
    implementation 'io.github.lucksiege:pictureselector:v2.7.0-rc06'// implementation "com.squareup.okio:okio:3.0.0-alpha.4"

https://github.com/LuckSiege/PictureSelector/blob/v2.7.0-rc06/picture_library/build.gradle
https://github.com/LuckSiege/PictureSelector/blob/v2.7.0-rc06/config.gradle
在这里插入图片描述
在这里插入图片描述

>>>>确实引用了implementation “com.squareup.okio:okio:3.0.0-alpha.4”

  • 测试下最新的版本3.10.6,发现没有 引用 okio库
    implementation 'io.github.lucksiege:pictureselector:v3.10.6'// 不包含okio

PictureSelector/build.gradle at v3.10.6 · LuckSiege/PictureSelector

在这里插入图片描述

>>>>将 okio库删除了


█ 相关资料

提示:这里是参考的相关文章

  1. 使用网站 mvnrepository 查询库的依赖
  2. 20019年前 如何查找第三方库(Gradle引用)的依赖? | 码农网 >>>>替换成setSelection(index,false)
  3. 2022-05-22 gradle依赖冲突的解决方式以及开发中遇到的相关问题_小凡特爱写代码的博客-CSDN博客_gradle冲突
  4. 2019-08-22 解决 android 依赖包重复导致的冲突问题_soha_dong的博客-CSDN博客_android 依赖包重复
  5. 2018-03-08 android解决okhttp依赖冲突 - yklszm - 博客园
  6. 2019-05-06 OkHttp 依赖冲突问题的解决方法_唐衡三的博客-CSDN博客_okhttp 依赖冲突

█ 免责声明

博主分享的所有文章内容,部分参考网上教程,引用大神高论,部分亲身实践,记下笔录,内容可能存在诸多不实之处,还望海涵,本内容仅供学习研究使用,切勿用于商业用途,若您是部分内容的作者,不喜欢此内容被分享出来,可联系博主说明相关情况通知删除,感谢您的理解与支持!

转载请注明出处:
https://blog.csdn.net/ljb568838953/article/details/126637399

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值