OKHTTP
整体流程
同步请求
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
首先实例化一个OkHttpClient
OkHttpClient
实例的newCall
方法接收一个Request
对象,该对象由Request
的内部类Builder
构造出来。
newCall
方法返回的是一个RealCall对象
那么实际上是在执行RealCall对象的execute()
方法
通过阅读execute()
方法,得知
execute()
仅仅执行一次,多次执行会报错- 其中调用
getResponseWithInterceptorChain
方法同步返回了Response
对象
在getResponseWithInterceptorChain
方法中,将许多拦截器加入了一个List中,然后构造了一个完整的请求对象进行网络请求,正是责任链模式,各自负责各节点的工作,如下:
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);
}
RealInterceptorChain
最后正是构造了RealInterceptorChain
对象并执行它的proceed
方法返回一个Response
对象。
在proceed
方法中,首先生成下一个RealInterceptorChain
对象,然后将这个对象传给该拦截器
RetryAndFollowUpInterceptor
是重试拦截器,是失败时重新开始的拦截器
利用while循环不停尝试,最大重试次数为20
BridgeInterceptor
是桥接拦截器
进一步封装Reponse对象
CacheInterceptor
缓存拦截器
有效地通过缓存减少网络请求的次数
- 判断是否需要返回缓存(即一般来说无网络就返回缓存)
- 有网络的情况下,判断返回的
Response
是否有更新,无更新就直接返回缓存,有更新就返回新的内容,并存入缓存。
ConnectInterceptor
连接拦截器,建立与服务器的连接
okhttp的连接是维护在一个连接池中的,
获取连接的流程:
- 如果能通过地址取到连接就返回,否则下一步
- 更换线路继续尝试获取连接,取到就返回,否则下一步
- 创建新的连接,建立与服务端的TCP连接
- 将新的连接加入连接池
CallServerInterceptor
网络请求连接器,负责向服务端发送数据
主要利用httpStream的readResponseHeaders()
方法获取response
异步请求
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//请求失败的回调
}
@Override
public void onResponse(Call call, Response response) throws IOException {
//请求成功的回调
}
});
与同步请求的不同在于,此处调用的是RealCall对象的enqueue()
方法
call, Response response) throws IOException {
//请求成功的回调
}
});
与同步请求的不同在于,此处调用的是RealCall对象的`enqueue()`方法
和同步请求流程相对比,异步请求流程比同步流程多了一步也就是将请求对象进行分发并放到线程池中去执行,至于拦截器分层、发起网络请求、数据返回流程等都是一样的。