本篇文章更像是学习下面这篇OKhttp后的读书笔记,看不懂我的请去看下面这篇文章
学习自,讲的特别好。需要仔细学习我觉得可以看一遍会收获很大:https://blog.piasy.com/2016/07/11/Understand-OkHttp/
在开始看这篇笔记之前,我强烈推荐
你学习
https://www.jianshu.com/p/51a61845e66a
生动举例讲述Http的全过程,到底为什么Tcp是3次握手
知识点1.创建client
OkHttpClient okHttpClient=new OkHttpClient();
创建过程使用了builder建造者模式
。建造者需要很多赋值,但是这里为什么会这么短一句话就可以呢?因为构造方法中写入了许多默认值(当然你也可以更改),当然可以看到默认的请求方式是Get请求
知识点2.发起http的请求
okHttpClient.newCall(request)
@Override public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
调用okHttpClient.newCall()返回的是RealCall,进入发现方法前面有@Override,证明不是继承就是接口实现。最上方可看到是实现 Call.Factory ,产生的newCall()。由以上可知RealCall才是真正的请求执行者
知识点3.同步网络请求
//同步请求的方法
Response response=okHttpClient.newCall(request).execute();
同步请求部分.png
(1)
Dispatcher:分发器
,在同步网络请求中,只是用来告知执行到了哪一步: client.dispatcher().executed(this);开始执行; client.dispatcher().finished(this);执行结束(2)网络请求的结果是
Response result = getResponseWithInterceptorChain();
,所以我们重点需要看这个地方。进入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);
}
a.从整体上来说,是有顺序的,是从上至下,依次执行
。最后的intercepter一定是CallServerInterceptor,用于和服务器实际通讯。由于此过程有顺序,所以前面的拦截器一定会执行重定向缓存等一系列操作
b.所有interceptor(拦截器)意义:
client.interceptors()
:初始化OKhttpclient添加的
RetryAndFollowUpInterceptor
:负责失败重试和重定向
BridgeInterceptor
:负责把用户构造的请求转换为发送到服务器的请求、把服务器返回的响应转换为用户友好的响应的
CacheInterceptor
:负责读取缓存直接返回、更新缓存
ConnectInterceptor
:负责和服务器建立连接
NetworkInterceptors
:配置 OkHttpClient时候设置的
CallServerInterceptor
:负责向服务器发送请求数据、从服务器读取响应数据
c.下面直接引用文章的内容:责任链模式
d.intercepter也是一种分层模式:每一个intercepter只需要关注自己的责任,各层之间通过约定的接口/协议进行合作
知识点4.异步网络请求
//发起异步请求的方法
Call call=okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
//RealCall-enqueue
@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
eventListener.callStart(this);
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
//Dispatcher-enqueue
synchronized void enqueue(AsyncCall call) {
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
readyAsyncCalls.add(call);
}
}
(1)Dispatcher:分发器
:在异步网络请求中,如果当前还能执行一个并发请求,那就立即执行,否则加入 readyAsyncCalls 队列,而正在执行的请求执行完毕之后,会调用 promoteCalls() 函数,来把 readyAsyncCalls 队列中的 AsyncCall “提升”为 runningAsyncCalls,并开始执行。调度器主要维护两个线程队列(异步缓存队列,异步执行队列 ),每当异步执行队列中的请求执行完成后,就会从异步缓存队列中抽取请求过来到异步线程池中执行,形成一个异步循环
总结:
全流程图.png1.
OkHttpClient
实现 Call.Factory,负责为 Request 创建 Call;2.
RealCall
为真正发起请求的3.
Dispatcher
在同步请求仅用于高知当前状态,在异步请求利用ExecutorService 实现,最终进行网络请求时和同步 execute() 接口一致,都是通过 getResponseWithInterceptorChain()
函数实现4.
getResponseWithInterceptorChain()
采用了责任链模式,每个拦截器依次处理,处理不了的就交付给下一个拦截器继续处理
网友评论