我正在尝试使用超简单单例创建翻新服务。这似乎在大多数时间都有效。例外,当我通过打开飞行模式测试连接断开时,http请求将按原样失败。但是当我关闭飞行模式时,请求将继续失败。我收到此错误:
HTTP FAILED: java.net.SocketTimeoutException: timeout
这是我正在使用的代码:
class ServiceGenerator {
private static ScanClient service = null;
static ScanClient createService(Class<ScanClient> serviceClass, Context context) {
if (service == null) {
String apiBaseUrl = Constants.RETROFIT_BASE_URL;
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(apiBaseUrl)
.addConverterFactory(GsonConverterFactory.create());
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
if (Constants.PHP_DEBUG) {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor()
.setLevel(HttpLoggingInterceptor.Level.BODY);
httpClient.addInterceptor(logging);
}
httpClient.addInterceptor(new ReceivedCookiesInterceptor(context));
httpClient.addInterceptor(new AddCookiesInterceptor(context));
builder.client(httpClient.build());
Retrofit retrofit = builder.build();
service = retrofit.create(serviceClass);
}
return service;
}
}
答案 0 :(得分:0)
您可以通过处理超时来做到这一点。
...
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
if (Constants.PHP_DEBUG) {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor()
.setLevel(HttpLoggingInterceptor.Level.BODY);
httpClient.addInterceptor(logging);
}
httpClient.connectTimeout(2, TimeUnit.MINUTES);
httpClient.writeTimeout(2, TimeUnit.MINUTES);
httpClient.readTimeout(2, TimeUnit.MINUTES);
httpClient.addInterceptor(new ReceivedCookiesInterceptor(context));
httpClient.addInterceptor(new AddCookiesInterceptor(context));
builder.client(httpClient.build());
...
答案 1 :(得分:0)
我不确定这是最好的解决方案,但是设置新的sslSocketFactory可以帮助
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
clientBuilder.eventListener(new EventListener() {
@Override
public void callStart(Call call) {
super.callStart(call);
}
@Override
public void dnsStart(Call call, String domainName) {
super.dnsStart(call, domainName);
}
@Override
public void dnsEnd(Call call, String domainName, List<InetAddress> inetAddressList) {
super.dnsEnd(call, domainName, inetAddressList);
}
@Override
public void connectStart(Call call, InetSocketAddress inetSocketAddress, Proxy proxy) {
super.connectStart(call, inetSocketAddress, proxy);
}
@Override
public void secureConnectStart(Call call) {
super.secureConnectStart(call);
}
@Override
public void secureConnectEnd(Call call, Handshake handshake) {
super.secureConnectEnd(call, handshake);
}
@Override
public void connectEnd(Call call, InetSocketAddress inetSocketAddress, Proxy proxy, Protocol protocol) {
super.connectEnd(call, inetSocketAddress, proxy, protocol);
}
@Override
public void connectFailed(Call call, InetSocketAddress inetSocketAddress, Proxy proxy, Protocol protocol, IOException ioe) {
super.connectFailed(call, inetSocketAddress, proxy, protocol, ioe);
}
@Override
public void connectionAcquired(Call call, Connection connection) {
super.connectionAcquired(call, connection);
}
@Override
public void connectionReleased(Call call, Connection connection) {
super.connectionReleased(call, connection);
}
@Override
public void requestHeadersStart(Call call) {
super.requestHeadersStart(call);
}
@Override
public void requestHeadersEnd(Call call, Request request) {
super.requestHeadersEnd(call, request);
}
@Override
public void requestBodyStart(Call call) {
super.requestBodyStart(call);
}
@Override
public void requestBodyEnd(Call call, long byteCount) {
super.requestBodyEnd(call, byteCount);
}
@Override
public void responseHeadersStart(Call call) {
super.responseHeadersStart(call);
}
@Override
public void responseHeadersEnd(Call call, Response response) {
super.responseHeadersEnd(call, response);
}
@Override
public void responseBodyStart(Call call) {
super.responseBodyStart(call);
}
@Override
public void responseBodyEnd(Call call, long byteCount) {
super.responseBodyEnd(call, byteCount);
}
@Override
public void callEnd(Call call) {
super.callEnd(call);
}
@Override
public void callFailed(Call call, IOException ioe) {
super.callFailed(call, ioe);
if (ioe instanceof SocketTimeoutException) {
reInitSslSocketFactory();
}
}
});
reInitSslSocketFactory方法:
private void reInitSslSocketFactory() {
try {
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new IllegalStateException("Unexpected default trust managers:"
+ Arrays.toString(trustManagers));
}
SSLContext sslContext = Platform.get().getSSLContext();
X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
sslContext.init(null, new TrustManager[]{trustManager}, null);
OkHttpClient okHttpClient = ((OkHttpClient) retrofit.callFactory()).newBuilder()
.sslSocketFactory(sslContext.getSocketFactory(), trustManager)
.build();
retrofit = retrofit.newBuilder().client(okHttpClient).build();
} catch (GeneralSecurityException e) {
throw assertionError("No System TLS", e); // The system has no TLS. Just give up.
}
}