OKHttp整体流程分析

OkHttp 的使用如下:

1
2
3
4
5
6
7
8
9
10
11
OkHttpClient client = new OkHttpClient();
String run(String url) throws IOException {
Request request = new Request.Builder()
.url(url)
.build();
try (Response response = client.newCall(request).execute()) {
return response.body().string();
}
}

newCall(request) 方法会返回 Call 对象,Call 接口类只有一个实现类 RealCall,看一下 RealCall 的execute() 方法。

RealCall 类的 execute() 方法调用了 getResponseWithInterceptorChain() 获取响应结果,getResponseWithInterceptorChain 方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 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);

采用类似职责链模式的方法,依次执行到各个拦截器的 intercept 方法。客户端最上层的请求数据依次经过各个拦截器处理后发给服务器,服务器的响应数据依次经过各个拦截器后返回给客户端,类似 TCP/IP 分层协议中对数据的处理。代码大致流程如下:

respone = Chain0.proceed

interceptor0.intercept(chain1) Chain1.proceed

interceptor1.intercept(chain2) Chain2.proceed

interceptor2.intercept(chain3)

整体流程图如下:

流程图

OkHttp 支持自定义拦截器,自定义拦截器类型分为两种: Application interceptor 和 Network Interceptor。应用拦截器只会被执行一次,网络拦截器可能会被执行多次(由于重定向和失败重试) 。

后面会依次分析各个拦截器的逻辑。OkHttp 本质是个 http 客户端。关于 http 内容可参考 rfc 文档、MDN web docs。