Java 改装不适用于特定版本的android
我在运行安卓4.3的仿真器上改装时遇到问题,我的设备在安卓4.4.2上,而相同的代码通常在另一个运行安卓7.1.1的仿真器上运行Java 改装不适用于特定版本的android,java,android,retrofit,retrofit2,Java,Android,Retrofit,Retrofit2,我在运行安卓4.3的仿真器上改装时遇到问题,我的设备在安卓4.4.2上,而相同的代码通常在另一个运行安卓7.1.1的仿真器上运行 每次尝试执行get请求时,都会出现超时异常 java.net.SocketTimeoutException: failed to connect to jsonplaceholder.typicode.com/2606:4700:30::681c:3f5 (port 443) after 10000ms at libcore.io.IoBridge.c
每次尝试执行
get
请求时,都会出现超时异常
java.net.SocketTimeoutException: failed to connect to jsonplaceholder.typicode.com/2606:4700:30::681c:3f5 (port 443) after 10000ms
at libcore.io.IoBridge.connectErrno(IoBridge.java:159)
at libcore.io.IoBridge.connect(IoBridge.java:112)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
at java.net.Socket.connect(Socket.java:842)
at okhttp3.internal.platform.AndroidPlatform.connectSocket(AndroidPlatform.java:73)
at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.java:246)
at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:166)
at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:257)
at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:135)
at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:114)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:254)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:200)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:841)
代码如下
public interface Api {
String BASE_URL = "https://jsonplaceholder.typicode.com/";
@GET("posts")
Call<ArrayList<Post>> getPosts();
}
公共接口Api{
字符串BASE_URL=”https://jsonplaceholder.typicode.com/";
@获取(“帖子”)
调用getPosts();
}
以及对api的调用
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Api.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
Api api = retrofit.create(Api.class);
Call<ArrayList<Post>> call = api.getPostes();
Log.i("RequestUrl", call.request().url().toString());
call.enqueue(new Callback<ArrayList<Post>>() {
@Override
public void onResponse(Call<ArrayList<Post>> call, Response<ArrayList<Post>> response) {
mPostsList.setValue(response.body());
}
@Override
public void onFailure(Call<ArrayList<Post>> call, Throwable t) {
Log.e("Posts", "Error occurred", t);
}
});
reformation-reformation=new-reformation.Builder()
.baseUrl(Api.BASE\u URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
Api=改装.create(Api.class);
Call Call=api.getPostes();
Log.i(“RequestUrl”,call.request().url().toString());
call.enqueue(新回调(){
@凌驾
公共void onResponse(调用、响应){
mPostsList.setValue(response.body());
}
@凌驾
失败时公共无效(调用调用,可丢弃的t){
Log.e(“Posts”,“发生错误”,t);
}
});
它的内容是java.net.SocketTimeoutException
,它最初建议提高客户端的连接超时值,正如本文所解释的-但是在查看当前的okhttp3.internal.platform.AndroidPlatform
时。。。这相当于暗示了不兼容的协议
服务器支持TLS 1.0,因为Android 4.x需要它(他们这边没有问题);问题在于,当前版本的OkHttp3
不再支持tls1.0
,因此握手永远不会发生(这就是为什么它会抛出这样一个误导性的SocketTimeoutException
而不是SSLHandshakeException
)
使用
OkHttp3
3.12.x
,默认配置MODERN\u TLS
-
但是可以指示OkHttp3
3.13.x
使用配置兼容\u TLS
:
/* ConnectionSpec.MODERN_TLS is the default value */
List tlsSpecs = Arrays.asList(ConnectionSpec.MODERN_TLS);
/* providing backwards-compatibility for API lower than Lollipop: */
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
tlsSpecs = Arrays.asList(ConnectionSpec.COMPATIBLE_TLS);
}
OkHttpClient client = new OkHttpClient.Builder()
.connectionSpecs(tlsSpecs)
.build();
请参阅,以获取可用的协议支持,请参见OkHttp3
版本。看起来,3.12.x
甚至已经支持tls1.3
,因为AndroidQ
将来需要它。它甚至可能不需要降级OkHttp3
,因为3.12.x
的MODERN_TLS
仍然支持TLSv1
,而在3.13.x
中它已被移动到COMPATIBLE_TLS
;仍然不确定3.14.x
即使使用当前版本的
OkHttp3
,仍然可以将所需的TLS 1.0
协议添加回ConnectionSpec.COMPATIBLE\u TLS
,因为这是一个ArrayList
的方法.add()
,没有任何保证,不会出现进一步的不兼容3.12.x
可能仍然是支持Android 4.x以后版本的最佳选择,甚至可能会有新功能的后端端口。21之前的Android缺少一些SSL,改型无法工作。使用google服务,您可以在HTTP请求生效后更新设备协议
//compile 'com.google.android.gms:play-services-base:11.0.0'
//remember to add the library in your dependencies
//compile 'com.google.android.gms:play-services-base:$currentVersion'
ProviderInstaller.installIfNeededAsync(this, new ProviderInstallListener() {
@Override
public void onProviderInstalled() {
//Do your http request here
}
@Override
public void onProviderInstallFailed(int errorCode, Intent recoveryIntent) {
//sad face :C is sad
}
});
如果您使用android 9(Pie)或28以上的android SDK,并通过改型通过api调用解决问题
将此行添加到您的清单android:usesCleartextTraffic=“true”
最后一段错了。您可以指示OkHttp使用兼容的,请参阅。这应该适用于TLS1.0。请注意,您使用的是比OkHttp 3.12更新的版本,因为这是最后一个支持Android 4.x及更早版本的版本。@aha
3.12.x的现代\u TLS
仍然支持TLSv1
,而在3.13.x
中,它已被添加到兼容的\u TLS
。。。因此,此问题仅适用于默认配置MODERN\u TLS
。版本3.13.x
仍应工作,但不使用默认配置;关于3.14.x
.Docs和完整的讨论不是很确定,可能我遗漏了一些东西,请指出@MartinZeitlerI猜测@cutiko指的是在KitKat之前不支持TLS 1.2的事实,您正在使用哪个版本的改装?请检查我的答案,好的,但我们只需要此配置来连接没有SSL(http)属性的api UseClearTextTraffic仅在api级别23及更高的版本中使用
//compile 'com.google.android.gms:play-services-base:11.0.0'
//remember to add the library in your dependencies
//compile 'com.google.android.gms:play-services-base:$currentVersion'
ProviderInstaller.installIfNeededAsync(this, new ProviderInstallListener() {
@Override
public void onProviderInstalled() {
//Do your http request here
}
@Override
public void onProviderInstallFailed(int errorCode, Intent recoveryIntent) {
//sad face :C is sad
}
});