- 场景
由于某个接口耗时比较长,故需要对okHttpClient添加动态的超时时间,来满足业务场景 - 处理方式
实现OkHttp动态添加超时时间 实现原理
查看Retrofit和OkHttpClient源码,根据Retrofit反射拿到OKHttpClient的信息并进行动态设置超时时间工具类地址
下载链接 http://download.csdn.net/download/gl_mine_csdn/10140891- 处理过程
public class DynamicConnectTimeout implements Interceptor {
private static final int CONNECT_LONG_TIMEOUT = 20;
private static final int CONNECT_SHORT_TIMEOUT = 10;
@Override
public Response intercept(Chain chain) throws IOException {
Request oldRequest = chain.request();
setDynamicConnectTimeout(oldRequest,mRetrofit,"add you need dynamic interface");
Request newRequest = oldRequest.newBuilder()
.method(oldRequest.method(), oldRequest.body())
.url(oldRequest.url())
.build();
return chain.proceed(newRequest);
}
/**
* 根据所需接口、进行动态设置网络超时时间
* @param oldRequest
* @param retrofit
*/
private void setDynamicConnectTimeout(Request oldRequest, Retrofit retrofit,String url) {
//动态设置超时时间
final String questUrl = oldRequest.url().url().toString();
try {
//1、private final okhttp3.Call.Factory callFactory; Retrofit 的源码 构造方法中
Field callFactoryField = retrofit.getClass().getDeclaredField("callFactory");
callFactoryField.setAccessible(true);
//2、callFactory = new OkHttpClient(); Retrofit 的源码 build()中
OkHttpClient client = (OkHttpClient) callFactoryField.get(retrofit);
//3、OkHttpClient(Builder builder) OkHttpClient 的源码 构造方法中
Field connectTimeoutField = client.getClass().getDeclaredField("connectTimeout");
connectTimeoutField.setAccessible(true);
//4、根据所需要的时间进行动态设置超时时间
if (questUrl.contains(url)) {
connectTimeoutField.setInt(client,CONNECT_LONG_TIMEOUT * 1000);
} else {
connectTimeoutField.setInt(client,CONNECT_SHORT_TIMEOUT * 1000);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}
- OkHttpClient 添加网络监听
builder.addInterceptor(new DynamicConnectTimeout());