OKhttp-基本工作流程&责任链模式原理

253 阅读4分钟

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开发者中Rxjava架构原理的以上是Android开发者中Rxjava架构原理的传送直达↓↓↓ :link.juejin.cn/?target=htt…里这个技术笔记。

总结:

整理一下上述流程,当调用getResponseWithInterceptorChain()方法后,初始化拦截器和链条,并为链条添加5个节点,后续调用链条的proceed()方法,proceed()会去创建一个新链条,并使下标加1,再执行当前链条的下标位置的拦截器的intercept()方法,并将刚才创建的链条当成参数传入intercept()方法,在拦截器的intercept()方法实现中,又会递归去调用传入链条的proceed()方法,直到链条执行结束。