当前位置: 首页 > 面试题库 >

改造不适用于特定版本的android

齐浩淼
2023-03-14
问题内容

我在运行Android 4.3的仿真器上使用Retrofit时遇到问题,并且设备在Android 4.4.2上运行,而相同的代码在运行Android
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的调用

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);
    }
});

问题答案:

它显示为java.net.SocketTimeoutException,起初建议提高客户端的连接超时值,正如在此答案中所解释的-
但在查看…的当前源代码时,okhttp3.internal.platform.AndroidPlatform这提示不兼容的协议。

服务器的SSL证书支持TLS 1.0,这对于Android 4.x来说是必需的(它们没有问题);问题在于,当前版本的OkHttp3不再支持TLS 1.0,因此握手将永远不会发生(这就是为什么它会引发误导SocketTimeoutException而不是SSLHandshakeException)的原因。

使用时OkHttp3 3.12.x,默认配置仍应支持它MODERN_TLS-

但是可以指示OkHttp3 3.13.x使用配置COMPATIBLE_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();

还必须将其设置为以下客户端Retrofit

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl(Api.BASE_URL)
    .addConverterFactory(GsonConverterFactory.create())
    .setClient(client)
    .build();

有关每个版本的可用协议支持,请参阅TLS配置历史记录OkHttp3。看起来,3.12.x甚至已经支持了TLS 1.3,因为将来Android需要它Q。它甚至可能不会被要求下级OkHttp3,因为MODERN_TLS3.12.x仍然支持TLSv1,而在3.13.x它已提前转移到COMPATIBLE_TLS;
仍然不确定3.14.x

即使使用最新版本的OkHttp3,也可能仍可以将所需的TLS 1.0协议重新添加到中ConnectionSpec.COMPATIBLE_TLS,因为这是一种ArrayList方法.add()-不做任何保证,不会再有不兼容的情况。3.12.x可能仍然是支持Android4.x及更高版本的最佳选择,甚至可能会有一些新功能的后继端口。



 类似资料:
  • 问题内容: 我知道有很多类似的问题,但是这种情况看起来确实很奇怪。对于Internet Explorer 11(Windows 7 Pro),@ font-face似乎已损坏。具体来说,版本:11.0.9600.17728,更新版本:11.0.18。 @ font-face在Chrome,Firefox,Safari,Opera(适用于Linux和Windows)上都可以正常工作。实际上,它甚至可

  • 我一直在发疯,想弄明白为什么最终的android改造没有发送帖子。这就是我所做的。在Laravel中,我设置了模型controller,更改了VerifyCsrfToken以允许api。然后设置路由web和api。所有这些都是通过邮递员测试的,而且都是有效的,但当我尝试通过android发布时,代码失败了。 这是我给Laravel的路线 网状物php 应用程序编程接口。php Androidapi

  • 我有两个版本的oracle,oracle Database 11g Enterprise Edition 11.2.0.1.0版本-生产版和oracle Database 11.g Enterprise Edition版本11.2-0.3.0版本-64位生产版 我有这个sql: 它适用于11.2.0.1.0,但在11.2.0.3.0上,我收到此错误: 我能做些什么来解决这个问题? 感谢。

  • 我的谷歌登录非常适合调试变体。但是当我尝试构建发布变体时,它停止工作......我提到了这个答案,但就我而言,我还没有上传到我的应用程序到Play商店。那么在这种情况下,我如何获得新的 sha1 密钥呢?

  • “技术人员”之前的简报对改装并不陌生,但我遇到了这种奇怪的行为,我很难理解和修复。我有两个web服务,在Postman和iOS中都能正常工作,但只有一个在改装中工作,而另一个不工作, 为我辩护,我可以说我得到了(未经授权的)响应,这意味着我能够点击服务器并得到API开发者辩护的结果,他说它在邮递员和其他设备中工作,所以不是服务问题 如果有改装专家告诉我,为了得到这个错误,我背后可能在做什么改装?

  • 问题内容: 有序词典是非常有用的结构,但是不幸的是,它们仅在3.1和2.7版本中才是最近的版本。在旧版本中如何使用有序词典? 问题答案: 我在pip python 2.6上安装了ordereddict