攔截器容器,裝載了所有攔截器
private List<Interceptor> interceptors = new ArrayList<>();
攔截器容器添加攔截器
public void addInterceptors(Interceptor interceptor) {
this.interceptors.add(interceptor);
}
創建OKhttp配置一個默認攔截器
OkHttpClient.Builder mOkHttpBuilder = new OkHttpClient.Builder()
.addNetworkInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
.addInterceptor(默認攔截器)
.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
默認攔截器實現:創建攔截器責任鏈表
@Override
public Response intercept(Chain chain) throws IOException {
return new TChain(interceptors, chain).proceed();
}
自定義責任鏈表類
class TChain implements Chain {
private List<Interceptor> interceptors;
private Chain chain;
private Request request;
private int index = 0;
public TChain(List<Interceptor> interceptors, Chain chain) {
this(interceptors, chain, chain.request(), 0);
}
private TChain(List<Interceptor> interceptors, Chain chain, Request request, int index) {
this.interceptors = interceptors;
this.chain = chain;
this.request = request;
this.index = index;
}
/**
* 依次取出攔截器鏈表中的每個攔截器去獲取Response
*
* @param request
* @return
* @throws IOException
*/
@Override
public Response proceed(Request request) throws IOException {
return index >= interceptors.size() ? chain.proceed(request) : interceptors.get(index).intercept(new TChain(interceptors, chain, this.request = request, index + 1));
}
@Override
public Request request() {
return request;
}
public Response proceed() throws IOException {
return proceed(this.request);
}
@Override
public Connection connection() {
return chain.connection();
}
@Override
public Call call() {
return chain.call();
}
@Override
public int connectTimeoutMillis() {
return chain.connectTimeoutMillis();
}
@Override
public Chain withConnectTimeout(int timeout, TimeUnit unit) {
return chain.withConnectTimeout(timeout, unit);
}
@Override
public int readTimeoutMillis() {
return chain.readTimeoutMillis();
}
@Override
public Chain withReadTimeout(int timeout, TimeUnit unit) {
return chain.withConnectTimeout(timeout, unit);
}
@Override
public int writeTimeoutMillis() {
return chain.writeTimeoutMillis();
}
@Override
public Chain withWriteTimeout(int timeout, TimeUnit unit) {
return chain.withWriteTimeout(timeout, unit);
}
}