Java 改装不适用于特定版本的android

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

我在运行安卓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.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
,因为Android
Q
将来需要它。它甚至可能不需要降级
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

            }

        });