要了解OKHttp先从用法开始去追源码
//首先创建一个客户端 client 跟服务器对接,可以在build()之前添加拦截器、连接池等属性
OkHttpClient client = new OkHttpClient.Builder().build();
//接着创建请求对象,可以在build()前添加请求头、请求体、URL地址
Request request = new Request.Builder().build();
//这里client.newCall实际上是newRealCall()来准备发起请求
Call call = client.newCall(request);
//无论是异步enqueue还是同步execute,都是通过调度器client.dispatcher()来放入请求队列中,最终分别调用了RealCall类、AsyncCall类的@Override protected void execute() {}方法
//call.enqueue();
call.execute();
接下来看在@Override protected void execute() {}
方法中是如何获得相应体的?
@Override protected void execute() {
...
Response result = getResponseWithInterceptorChain();
...
}
从getResponseWithInterceptorChain()
方法中可以看到先是添加一系列的拦截器Interceptor
,然后调用了chain.proceed(originalRequest)
来返回response
Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
//TODO 7、责任链 倒序调用
List<Interceptor> interceptors = new ArrayList<>();
interceptors.addAll(client.interceptors());
//TODO 6、处理重试与重定向
interceptors.add(retryAndFollowUpInterceptor);
//TODO 5、处理 配置请求头 请求体等信息
interceptors.add(new BridgeInterceptor(client.cookieJar()));
//TODO 4、处理 缓存配置 根据条件(存在响应缓存并被设置为不变的或者响应在有效期内)返回缓存响应
//TODO 3、设置请求头(If-None-Match、If-Modified-Since等) 服务器可能返回304(未修改)
interceptors.add(new CacheInterceptor(client.internalCache()));
//TODO 2、连接服务器
interceptors.add(new ConnectInterceptor(client));
if (!forWebSocket) {
interceptors.addAll(client.networkInterceptors());
}
//TODO 1、执行流操作(写出请求体、获得响应数据)
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);
}
}
在proceed()
方法中又创建新的拦截链,chain中的拦截器集合index+1,也就是说从上面的List<Interceptor> interceptors = new ArrayList<>();
拦截器集合中拿出index+1的Interceptor,并且调用了相应拦截器的intercept()
方法
public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec,
RealConnection connection) throws IOException {
if (index >= interceptors.size()) throw new AssertionError();
calls++;
...省略...
//创建新的拦截链,链中的拦截器集合index+1
// Call the next interceptor in the chain.
RealInterceptorChain next = new RealInterceptorChain(interceptors, streamAllocation, httpCodec,
connection, index + 1, request, call, eventListener, connectTimeout, readTimeout,
writeTimeout);
//执行当前的拦截器 默认是:retryAndFollowUpInterceptor
Interceptor interceptor = interceptors.get(index);
Response response = interceptor.intercept(next);
...省略...
return response;
}
在拦截器的interceptor()
里,它又调用了chain的chain.proceed(networkRequest);
方法,其中networkRequest
就是上面的next
。就像递归一样,直到interceptors.add(new CallServerInterceptor(forWebSocket));
执行流操作获得相应体才返回上一层并执行完上一层的内容继续返回
//TODO 执行下一个拦截器
Response networkResponse = null;
try {
networkResponse = chain.proceed(networkRequest);
} finally {