一,概述
在OKHttp原码分析(一)最后讲到无论是同步请求还是异步请求都殊途同归到了RealCall的getResponseWithInterceptorChain方法。这篇blog主要讲解RealCall的getResponseWithInterceptorChain方法。
二,getResponseWithInterceptorChain方法源码
private Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
List<Interceptor> interceptors = new ArrayList<>();
interceptors.addAll(client.interceptors());
interceptors.add(retryAndFollowUpInterceptor);
interceptors.add(new BridgeInterceptor(client.cookieJar()));
interceptors.add(new CacheInterceptor(client.internalCache()));
interceptors.add(new ConnectInterceptor(client));
if (!retryAndFollowUpInterceptor.isForWebSocket()) {
interceptors.addAll(client.networkInterceptors());
}
interceptors.add(new CallServerInterceptor(
retryAndFollowUpInterceptor.isForWebSocket()));
Interceptor.Chain chain = new RealInterceptorChain(
interceptors, null, null, null, 0, originalRequest);
return chain.proceed(originalRequest);
}
注意点:
- 方法的返回值是Response 。这个就是网络请求的目的,得到的数据都封装在Response 对象中。
- 拦截器的使用。在方法的第一行中就创建了interceptors 集合,然后紧接着放进去很多拦截器对象。
- RealInterceptorChain类的proceed方法。getResponseWithInterceptorChain方法的最后创建了RealInterceptorChain对象,并调用proceed方法。Response 对象就有由RealInterceptorChain类的proceed方法返回的。
下面看RealInterceptorChain类的proceed方法的原码。
三,RealInterceptorChain类的proceed方法的原码
public Response proceed(Request request, StreamAllocation streamAllocation, HttpStream httpStream,Connection connection) throws IOException {
if (index >= interceptors.size()) throw new AssertionError();
calls++;
// If we already have a stream, confirm that this is the only call to chain.proceed().
if (this.httpStream != null && calls > 1) {
throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
+ " must call proceed() exactly once");
}
// Call the next interceptor in the chain.
RealInterceptorChain next = new RealInterceptorChain(
interceptors, streamAllocation, httpStream, connection, index + 1, request);
Interceptor interceptor = interceptors.get(index);
Response response = interceptor.intercept(next);
return response;
}
分析:
- 注意index和calls两个整形字段,如果index大于等于集合的长度,calls就++,calls大于1就会抛出异常。所以在正常情况下index是小于集合的长度的。
- index的初始化在RealInterceptorChain的构造方法中,也就是在getResponseWithInterceptorChain放中创建RealInterceptorChain对象时被初始化的。我们发现初始化值是0。
- 在该方法末尾再次创建RealInterceptorChain对象,此时index值是1。然后得到拦截器对象,调用拦截器的intercept方法,并把index等于1的RealInterceptorChain对象传递过去。
- interceptor的intercept方法的返回值是Response 。注意Response 是从这儿来的。