如何修复Retrofit中的SSL握手超时问题

11

在我的应用程序中,我想从服务器获取数据并将其显示在RecyclerView中。
为了从服务器获取数据,我使用Retrofit2,并编写以下代码。
但是当应用程序运行一段时间后,在Retrofit2onFailure中会显示E/priceResLog:Err:SSL握手超时

我的代码:

public class ApiUtilsPrice {

    private static final String BASE_URL = "https://core.arzws.com/";
    private static Retrofit retrofit = null;

    public static Retrofit getClient() {

        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .readTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .connectTimeout(60, TimeUnit.SECONDS)
                .build();

        if (retrofit == null) {
            retrofit = new Retrofit.Builder()
                    .client(okHttpClient)
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return retrofit;
    }
}

活动代码:

private void getCoinData() {
    loaderLayout(true);
    Call<GoldListResponse> call = apiInterface.getGoldPrice();
    call.enqueue(new Callback<GoldListResponse>() {
        @Override
        public void onResponse(Call<GoldListResponse> call, Response<GoldListResponse> response) {
            if (response.isSuccessful()) {
                if (response.body() != null) {
                    loaderLayout(false);
                    model.clear();
                    model.addAll(response.body().getGoldBoard());
                    coinAdapter.notifyDataSetChanged();
                    isSendApi = true;
                }
            }
        }

        @Override
        public void onFailure(Call<GoldListResponse> call, Throwable t) {
            Log.e("priceResLog", "Err : " + t.getMessage());
        }
    });
}

我该如何解决它?请帮助我,谢谢。

将超时时间从60增加到90。 - Hemant Parmar
@HemantParmar,为什么? - WoW.j
你需要为Retrofit添加默认证书。 - ManishNegi
@ManishNegi,你能给我发送代码吗?因为我是个业余爱好者,真的需要你的帮助。 - WoW.j
问题解决了吗? - Bolt UIX
显示剩余4条评论
1个回答

8
请添加以下代码片段:
public Retrofit getRetrofit(Gson gson) {
            return new Retrofit.Builder()
                    .baseUrl(ZoneApplication.getContext().getString(R.string.feed_data_base_url))
                    .client(HttpClientService.getUnsafeOkHttpClient())
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .addConverterFactory(new NullOnEmptyConverterFactory())
                    .addConverterFactory(GsonConverterFactory.create(gson))
                    .build();

        }

或者更改您的代码为
public static Retrofit getClient() {

        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .readTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .connectTimeout(60, TimeUnit.SECONDS)
                .build();

        if (retrofit == null) {
            retrofit = new Retrofit.Builder()
                    .client(HttpClientService.getUnsafeOkHttpClient())
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return retrofit;
    }

创建另一个名为HttpClientService的类,并添加以下代码。
public class HttpClientService {
    public static OkHttpClient getUnsafeOkHttpClient() {

        try {
            final TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        @SuppressLint("TrustAllX509TrustManager")
                        @Override
                        public void checkClientTrusted(
                                java.security.cert.X509Certificate[] chain,
                                String authType) {
                            //Do nothing
                        }

                        @SuppressLint("TrustAllX509TrustManager")
                        @Override
                        public void checkServerTrusted(
                                java.security.cert.X509Certificate[] chain,
                                String authType) {
                            //Do nothing
                        }

                        @Override
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                            return new java.security.cert.X509Certificate[0];
                        }
                    }};
            final SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, trustAllCerts,
                    new java.security.SecureRandom());

            final SSLSocketFactory sslSocketFactory = sslContext
                    .getSocketFactory();

            OkHttpClient okHttpClient = new OkHttpClient.Builder()
                    .sslSocketFactory(sslSocketFactory)
                    .hostnameVerifier(org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
                    .build();
            return okHttpClient;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }
}

你可以把你的Skype ID发给我吗?谢谢。 - WoW.j
1
我不理解创建okHttpClient实例的用途,如果我们将HttpClientService.getUnsafeOkHttpClient()作为客户端传递,那还有什么意义? - Axay Prajapati
它真的修复了旧版安卓上的https连接。谢谢! - Serg Burlaka
@deprecated [SSLSocketFactory],是否有任何备用语法? - Bolt UIX

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接