OKhttp工作的大致流程
整体流程
(1)、当我们通过OkhttpClient创立一个okHttpClient 、Request 、Call,并发起同步或者异步请求时;
(2)、okhttp会通过Dispatcher对我们所有的Call(RealCall实现类)进行统一管理,并通过execute()及enqueue()方法对同步或者异步请求进行执行; (3)、execute()及enqueue()这两个方法会最终调用RealCall中的getResponseWithInterceptorChain()方法,从阻拦器链中获取返回结果; (4)、拦截器链中,依次通过ApplicationInterceptor(应用拦截器)、RetryAndFollowUpInterceptor(重定向阻拦器)、BridgeInterceptor(桥接阻拦器)、CacheInterceptor(缓存阻拦器)、ConnectInterceptor(连接阻拦器)、NetwrokInterceptor(网络拦截器)、CallServerInterceptor(请求阻拦器)对请求依次处理,与服务的建立连接后,获取返回数据,再经过上述阻拦器依次解决后,最后将结果返回给调用方。
提供两张图便于了解和记忆:
okhttp整体流程1
OkHttp Response的返回整体流程属于责任链模式,本篇文章重点分析其中的责任链模式。
先说结论:OkHttp中有一个链条类,以及许多节点类,节点可以放在链条上,将需要发送的Request交给链条,启动链条,首节点就可以对Request进行加工并继续向下传递,最后一个节点将请求发出,当最后一个节点收到Response后,逐步向上传递,最终回到首节点。
流程如下图:
黑线代表Request的流向,红线代表Response的流向,在流向的过程中上游可以对下游的Request或Response进行加工处理。
在OkHttp原理第一篇—使用与分发机制中我们得出结论,无论异步请求还是同步请求,Response都是调用RealCall中的 getResponseWithInterceptorChain()方法返回的,因此我们在从方法开始分析。
RealCall#getResponseWithInterceptorChain
@Throws(IOException::class)
internal fun getResponseWithInterceptorChain(): Response {
// Build a full stack of interceptors.
//初始化拦截器数组
val interceptors = mutableListOf<Interceptor>()
interceptors += client.interceptors //用户自定义的节点,可在构建Client时加入自己的节点
interceptors += RetryAndFollowUpInterceptor(client)
interceptors += BridgeInterceptor(client.cookieJar)
interceptors += CacheInterceptor(client.cache)
interceptors += ConnectInterceptor
//是否属于webSocket协议链接,若是则添加networkInterceptors
if (!forWebSocket) {
interceptors += client.networkInterceptors
}
interceptors += CallServerInterceptor(forWebSocket)
//创建Chain链条
val chain = RealInterceptorChain(
call = this, //当前请求的Call(Request的载体)
interceptors = interceptors, //节点数组
index = 0, //目前需要执行的节点下标
exchange = null,
request = originalRequest, //原先的请求,后续会对请求进行再次封装
connectTimeoutMillis = client.connectTimeoutMillis, //超时时间
readTimeoutMillis = client.readTimeoutMillis,
writeTimeoutMillis = client.writeTimeoutMillis
)
...
//链条执行,下面分析
val response = chain.proceed(originalRequest)
...
return response
...
}
以HTTP请求分析,去掉自定义节点,此时链条会存在5个节点(在OkHttp中节点叫做拦截器,下文中全部使用拦截器):
- RetryAndFollowUpInterceptor 重试与重定向拦截器,主要处理错误信息进行重试和重定向操作
- BridgeInterceptor 桥接拦截器,对HTTP请求头进行封装,并处理请求体的压缩
- CacheInterceptor 缓存拦截器, 处理HTTP的缓存操作
- ConnectInterceptor 连接拦截器,建立Socket连接
- CallServerInterceptor请求拦截器,对Socket的输入流和输出流进行操作,真正的请求发起者和相应接收者
上述拦截器的作用还无需理解,此小节重点分析OkHttp的责任链的执行过程。
@Throws(IOException::class)
override fun proceed(request: Request): Response {
...
//创建一个新的链条,使当前下标加1,看下1中分析copy函数
val next = copy(index = index + 1, request = request)
val interceptor = interceptors[index]
@Suppress("USELESS_ELVIS")
//执行节点的处理,将下标加1的next链条交给当前拦截器,看下2,分析当前节点如何启动下一个节点
val response = interceptor.intercept(next) ?: throw NullPointerException(
"interceptor $interceptor returned null")
...
return response
}
1.RealInterceptorChain#copy
返回一个新的RealInterceptorChain
internal fun copy(
index: Int = this.index,
exchange: Exchange? = this.exchange,
request: Request = this.request,
connectTimeoutMillis: Int = this.connectTimeoutMillis,
readTimeoutMillis: Int = this.readTimeoutMillis,
writeTimeoutMillis: Int = this.writeTimeoutMillis
) = RealInterceptorChain(call, interceptors, index, exchange, request, connectTimeoutMillis,
readTimeoutMillis, writeTimeoutMillis)
2.RetryAndFollowUpInterceptor,BridgeInterceptor,CacheInterceptor,ConnectInterceptor#intercept
override fun intercept(chain: Interceptor.Chain): Response {
val realChain = chain as RealInterceptorChain
var request = chain.request
//对Request进行处理
...
//进行递归,回到上的proceed()方法,此时index下标已经+1,执行下一个拦截器的处理
response = realChain.proceed(request)
//对response进行处理
...
return response
}
前四个拦截器的处理方法类似,第五个拦截器会有所不同,其Response会直接通过网路返回的数据进行构建,不会再往下传递。
以上就是okhttp的基本操作流程与他的责任链模型学习;更多okhttp技术与Android开发技术可以参考《Android核心技术手册》这个技术笔记。
总结:
整理一下上述流程,当调用getResponseWithInterceptorChain()方法后,初始化拦截器和链条,并为链条添加5个节点,后续调用链条的proceed()方法,proceed()会去创建一个新链条,并使下标加1,再执行当前链条的下标位置的拦截器的intercept()方法,并将刚才创建的链条当成参数传入intercept()方法,在拦截器的intercept()方法实现中,又会递归去调用传入链条的proceed()方法,直到链条执行结束。