█ 【安卓学习之常见问题】gradle依赖冲突
█ 系列文章目录
提示:这里是收集了和文件分享有关的文章
- 【安卓学习之常见问题】android路径及文件问题
- 【安卓学习之常见问题】文件分享–文件不存在
- 【安卓学习之常见问题】自定义组件-刷新后跳到第一行
- 【安卓学习之常见问题】初始化spinner、CheckBox和SeekBar不触发事件
- 【安卓学习之常见问题】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
-
okhttp:3.9.0 和 okhttp:3.4.1 类 HttpUrl中也找不到getHttpUrlChecked方法,在Internal中可以找到:
-
okhttp3框架源码地址: https://github.com/square/okhttp,最早版本的使用的是okhttp 2.5.0版本,不过也没看到这个方法:
parent-2.5.0/okhttp/src/main/java/com/squareup/okhttp/HttpUrl.java
parent-2.5.0/okhttp/src/main/java/com/squareup/okhttp/internal/Internal.java
█ 依赖正常的解决方法
- 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的版本怎么会不一样?
- 查下 okhttp:3.4.1依赖什么?
Maven Repository: com.squareup.okhttp3 » okhttp » 3.4.1
implementation "com.squareup.okio:okio:1.9.0"
>>>>上面显示的明明是1.13.0
- 查下okhttp-urlconnection:3.4.1依赖什么?
https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp-urlconnection/3.4.1
implementation "com.squareup.okhttp3:okhttp:3.4.1"
implementation "org.codehaus.mojo:animal-sniffer-annotations:1.11"
>>>>上面显示的明明是3.9.0,看了是最后一个的版本更高了
- 查下logging-interceptor:3.9.0依赖什么?
Maven Repository: com.squareup.okhttp3 » logging-interceptor » 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库删除了
█ 相关资料
提示:这里是参考的相关文章
- 使用网站 mvnrepository 查询库的依赖
- 20019年前 如何查找第三方库(Gradle引用)的依赖? | 码农网 >>>>替换成setSelection(index,false)
- 2022-05-22 gradle依赖冲突的解决方式以及开发中遇到的相关问题_小凡特爱写代码的博客-CSDN博客_gradle冲突
- 2019-08-22 解决 android 依赖包重复导致的冲突问题_soha_dong的博客-CSDN博客_android 依赖包重复
- 2018-03-08 android解决okhttp依赖冲突 - yklszm - 博客园
- 2019-05-06 OkHttp 依赖冲突问题的解决方法_唐衡三的博客-CSDN博客_okhttp 依赖冲突
█ 免责声明
博主分享的所有文章内容,部分参考网上教程,引用大神高论,部分亲身实践,记下笔录,内容可能存在诸多不实之处,还望海涵,本内容仅供学习研究使用,切勿用于商业用途,若您是部分内容的作者,不喜欢此内容被分享出来,可联系博主说明相关情况通知删除,感谢您的理解与支持! |
---|
转载请注明出处:
https://blog.csdn.net/ljb568838953/article/details/126637399