Okhttp的大体流程
- 通过创建OKhttpClient创建一个Call,发起同步或者异步请求。
- Dispatcher对创建的RealCall(Call具体实现类)进行统一管理,然后execute()或者enqueue()进行同步或者异步请求。
- execute()会调用RealCall中的getResponseWithInterceptorChain()方法,拦截器中拦截结果。
- 拦截器,依次通过RetryAndFollowUpIntercepter(重定向拦截器),BridgeInterceptor(桥接拦截器),CacheInterceptor(缓存浏览器),ConnectInterceptor(连接拦截器),CallServerInterceptor(网络拦截器)依次进行请求,最后获取返回数据,依次才通过上面的拦截器,最后做结果的处理。
OkhttpClient.Builder->OkhttpClient->newCall->RealCall->execute()->RealCall.getResponseWithInterceptorChain()->五个Interceptor->procceed()启动链式调用。
拦截器作用
- RetryAndFollowUpInterceptor主要负责重定向。
构建一个StreamAllocation 对象,StreamAllocation 负责管理 Connection,Stream,Call三个实体类。一般就是网络请求失败后进行重试,服务器返回当前请求需要进行重定向直接发起新的请求,条件允许的复用当前的链接。 - BridgeInterceptor
实际应用中用到的就是对请求头以及返回结果进行解压保持Cookie等操作。
主要作用: 设置内容长度,内容编码。设置gzip压缩。添加cookie ,添加Host,Keep-live 等, - CacheInterceptor 主要是读取缓存和更新缓存。
具体就是:当网络请求有符合的Cache直接返回Cache,服务器返回更新时候刷新Cache,如果当前Cahce失效删除掉。 - ConnectInterceptor:负责和服务器建立链接
使用StreamAllocation.newStream来和服务器建立链接,返回输入输出流(HttpCodec)实际上是通过StreamAllcocation的findConnection 寻找一个可用的Connection,调用connect方法,最后使用socket与服务器建立链接。 - CallServerInterceptor :从服务器读取响应的数据
把请求的Request 写入服务器,从服务器读取Response。
连接池概述
Okhttp 支持5个keeplive 默认链接生命是5分钟,通过ConnectionPool进行管理。
ConnectionPool 在内部使用一个异步线程来清理连接。
多路复用就是发起请求之前点调用nextConnection()来获取一个Connection()对象,如果ConnectionPool能获取这个对象那么就直接使用,没有就走createnextConnection()来创建一个新的Connection()对象。
请求分发器 Dispatcher
Dispatcher 是一个任务调度器,它内部维护了三个双端队列
- readyAsyncCalls:准备运行的异步请求。
- runningAsyncCalls:正在运行的异步操作。
- runningSyncCalls:正在运行的同步操作。
- 同步请求会直接把请求的添加到正在运行的同步队列中runningSysncCalls
- 异步请求会做一个判断:
- 如果正在运行的不超过64,而且同一个Host下请求不超过 5 会添加到正在运行当中去,否则就会添加等待当中去。
核心点总结一下
1.OkhttpClient 有两种请求:同步和异步
- 同步请求就是直接加入的队列中去了,然后直接调用了getResponseWIthInterceptorChain()
- 异步请求就是要通过两个队列 一个等待队列一个正在执行的队列。
- Dispatch调度器
- 初始化了一个线程池,无核心的线程池,定义了60S的空闲时间,超过就会回收了。
- 通过ThreadFactory生产线程定义线程名称。
- SynchronousQueue同步队列,有空线程直接从线程池中取,没有就直接创建一个。
- 这个线程设计的概念核心线程数是0 是为了没有网络请求的时候,避免资源浪费。
3.从中学到的一些设计模式:
- 建造者模式 OkHttpClient与Request的构建都用到了构建者模式
- 外观模式: OkHttp使用了外观模式,将整个系统的复杂性给隐藏起来,将子系统接口通过一个客户端OkHttpClient统一暴露出来
- 责任连模式:OKHttp的核心就是责任链模式,通过5个默认拦截器构成的责任链完成请求的配置
-工程模式:ThradFactory