接上面的分析,在获取请求response的时候,都调用了如下代码
Response response = getResponseWithInterceptorChain();
我们跟进去看一下
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 (!forWebSocket) { interceptors.addAll(client.networkInterceptors()); } interceptors.add(new CallServerInterceptor(forWebSocket)); Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0, originalRequest, this, eventListener, client.connectTimeoutMillis(), client.readTimeoutMillis(), client.writeTimeoutMillis()); return chain.proceed(originalRequest); }
上面的代码可以看到,首先添加了client.intercepors(),它们就是application 拦截器,然后添加了上篇文章介绍的五种内部拦截器,最后又添加了network拦截器
再看下面的代码
Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0, originalRequest, this, eventListener, client.connectTimeoutMillis(), client.readTimeoutMillis(), client.writeTimeoutMillis())
创建了RealInterceptorChain这个对象,将前面创建好的拦截器list传入,这样就完成了第一步。然后调用了chain的proceed()方法
@Override public Response proceed(Request request) throws IOException { return proceed(request, streamAllocation, httpCodec, connection); }
最终调用了四个参数的proceed方法,接着看
public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec, RealConnection connection) throws IOException { if (index >= interceptors.size()) throw new AssertionError(); calls++; // If we already have a stream, confirm that the incoming request will use it. if (this.httpCodec != null && !this.connection.supportsUrl(request.url())) { throw new IllegalStateException("network interceptor " + interceptors.get(index - 1) + " must retain the same host and port"); } // If we already have a stream, confirm that this is the only call to chain.proceed(). if (this.httpCodec != 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, httpCodec, connection, index + 1, request, call, eventListener, connectTimeout, readTimeout, writeTimeout); Interceptor interceptor = interceptors.get(index); Response response = interceptor.intercept(next); // Confirm that the next interceptor made its required call to chain.proceed(). if (httpCodec != null && index + 1 < interceptors.size() && next.calls != 1) { throw new IllegalStateException("network interceptor " + interceptor + " must call proceed() exactly once"); } // Confirm that the intercepted response isn't null. if (response == null) { throw new NullPointerException("interceptor " + interceptor + " returned null"); } if (response.body() == null) { throw new IllegalStateException( "interceptor " + interceptor + " returned a response with no body"); } return response; }
这个方法比较长,我们挑重点看
// Call the next interceptor in the chain. RealInterceptorChain next = new RealInterceptorChain(interceptors, streamAllocation, httpCodec, connection, index + 1, request, call, eventListener, connectTimeout, readTimeout, writeTimeout); Interceptor interceptor = interceptors.get(index); Response response = interceptor.intercept(next);
上面这段代码也创建了一个拦截器链,这和刚才创建的区别在于他传入的参数是index+1,就传入了下一个拦截器,这样就把我们的整个拦截器构造成了一个链条,设计很巧妙喔。第三块获取response的代码,传入的是刚才构造的next拦截器链。
总结一下
1.创建一系列拦截器,放入一个拦截器list当中
2.创建一个拦截器链对象,并执行拦截器链的proceed方法,这里注意,执行的是下一个拦截器的intercept方法。
这里我们看一下intercept方法,这里执行的是chain的proceed方法,这样就印证了我们上面的说法,整个拦截器链完整的交替执行。
response = realChain.proceed(request, streamAllocation, null, null); releaseConnection = false;
这里,可以把OkHttp的网络请求看成一个个拦截器的执行他的intercept方法的过程,这样应该比较好理解了。
再次总结一下
1.在发起请求前对Request进行处理
2.调用下一个拦截器,获取response
3.对response处理,返回给上一个拦截器