上回书说到OkHttp的基本使用,其实平时也不单独使用OkHttp来做网络请求,都是搭配Retrofit来请求网络数据。Retrofit+okhttp基本使用下一章在说,今天写一下OkHttp的源码分析以及工作流程。
先上图(有图才能发现真相):
OkHttp请求流程图
从流程图中可以看出,无论是同步请求还是异步请求,最终都是交给RealCall#getResponseWithInterceptorChain()执行网络请求操作。
RealCall#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);
}
在getResponseWithInterceptorChain OkHttp创建了一个列表对象之后把 client 中的拦截器、重连拦截器(RetryAndFollowUpInterceptor)、桥拦截器(BridgeInterceptor)、缓存拦截器(CacheInterceptor)、网络连接拦截器(ConnectInterceptor)和服务器请求拦截器(CallServerInterceptor)等依次加入到列表中。然后,我们用这个列表创建了一个Interceptor.Chain(拦截器链)。这里使用了责任链设计模式,每当一个拦截器执行完毕之后会调用下一个拦截器或者不调用并返回结果。显然,我们最终拿到的响应就是这个链条执行之后返回的结果。当我们自定义一个拦截器的时候,也会被加入到这个拦截器链条里。
在getResponseWithInterceptorChain各个拦截器的功能如下:
- 在配置 OkHttpClient 时设置的 interceptors(如一些自定义的拦截器);
- 负责请求失败时重试以及重定向的 RetryAndFollowUpInterceptor;
- 负责把用户构造的请求转换为发送到服务器的请求、把服务器返回的响应转换为用户友好的响应的 BridgeInterceptor;
- 负责读取缓存直接返回、更新缓存的 CacheInterceptor;
- 负责和服务器建立连接的 ConnectInterceptor;
- 配置 OkHttpClient 时设置的 networkInterceptors;
- 负责向服务器发送请求数据、从服务器读取响应数据的 CallServerInterceptor。
Interceptor(拦截器)
OkHttp的作者之一这样形容它:
the whole thing is just a stack of built-in interceptors.
所以拦截器是OkHttp最核心的东西,也是广大面试官必问的点。
Interceptor其实不是说只是用来负责一些额外的操作处理(比如 缓存、异常拦截处理等),它在OkHttp中实际上是把网络请求流程中的:网络请求、缓存、异常处理等功能都统一起来,每一个功能就是一个Interceptor,然后所有的Interceptor连接在一起形成一个 Interceptor.Chain,最终圆满完成一次网络请求。