OkHttp源码简单解析

在这里插入图片描述
使用流程
1.创建OkHttpClient对象
默认直接new OkHttpClient()创建,其实内部是通过一个建造者模式创建的,使用默认配置。

2.发起Http请求
在这里插入图片描述
Requst通过Request.Builder()创建,client.newCall(Request)返回一个call,newCall()返回的是一个RealCall对象。
Call的execute()是同步方法,enqueue()是异步

3.同步网络请求execute()
在这里插入图片描述
(1)检查call是否被执行,每个call只能执行一次,如果想要一样的call,可以通过call.clone()得到
(2)利用client.dispatcher()来进行实际的执行。dispatcher时同步和异步的HTTP请求策略。executed()将call将入执行队列。
(3)getResponseWithInterceptorChain(),通过一系列拦截器interceptor,发送请求返回结果。这里才是请求真正执行和返回结果的地方。
(4)通知dispatcher执行完成。将call移出队列
在同步过程中,dispatcher主要是告诉我们执行状态,比如开始执行、执行完毕,将call添加移出队列。在异步流程中会有更多的参与

4.Inteceptor
Inteceptor负责拦截请求进行额外处理,把实际的网络请求、缓存、透明压缩等功能都统一起来。
在getResponseWithInterceptorChain()中首先会创建一个interceptors集合,依次加入:
(1)interceptors:配置OkHttpClient设置的,client.interceptors()。
(2)RetryAndFollowUpInterceptor:负责失败重试以及重定向
(3)BridgeInterceptor:负责把用户构造的请求转换为发送到服务器的请求、把服务器返回的响应转换为用户友好的响应。
(4)CacheInterceptor:负责读取缓存直接返回、更新缓存
(5)ConnectInterceptor:负责和服务器建立连接
(6)networkInterceptor:配置OkHttpClient时设置的,client.networkInterceptors()。根据forWebSocket(boolean)设置,默认false,如果!forWebSocket,加入networkInterceptor
(7)CallServerInterceptor:负责向服务器发送请求数据、从服务器读取响应数据。
Interceptor采用责任链模式,每一个Interceptor负责一部分工作,最后一个Interceptor一定是负责和服务器实际通讯的,重定向缓存一定是在实际通讯之前。

5.异步网络请求enqueue()
RealCall
在这里插入图片描述
Dispatcher
在这里插入图片描述
首先要判断Call是否被执行,是则抛出异常,不是则标记为是,这个过程在synchronized中执行。
然后调用client.dispatcher().enqueue(new AsyncCall())
在异步的dispatcher,直接将call将入异步待执行队列,然后执行promoteAndExecute()。
promoteAndExecute()

在promoteAndExecute中,有一个List记录可以执行的call,首先遍历readyAsyncCalls队列。
首先判断runningAsyncCalls正在执行的calls的数量是否大于最大请求数,如果大于等于,退出循环,执行List中的请求。
如果小于,检测当前call的host数量是否大于最大请求host数,如果大于等于,检查下一个call。
如果上面两项都满足,移出readyAsyncCalls,加入可执行list和runningAsyncCalls。
变量结束,通过线程池执行list中的call,执行
RealCall里还有一个final内部类AsyncCall,这个类负责执行异步call,RealCall负责同步。同步没有回调,直接返回结果;异步有回调,成功回调中返回结果。

总结:流程
1.创建OkHttpClient,虽然是直接new 创建,但其实内部是通过建造者模式创建的。

2.创建Request,通过建造者模式创建请求。

3.创建Call,通过client.newCall(Request)传入之前创建的请求,得到一个RealCall。
RealCall内部有个final内部类AsycnCall,RealCall负责同步网络请求,AsyncCall负责异步。
Client有个dispatcher变量。
对于同步请求,dispatcher有个runningSyncCalls队列,储存加入的RealCall,执行完毕移出队列。
对于异步请求,有两个队列:runningAsyncCalls和readyAsyncCalls,分别储存正在执行的AsyncCall和准备执行的AsyncCall。

4.发送同步请求,通过Call的execute()执行。首先判断是否执行过,执行过抛出异常;没执行过加入dispatcher的runningSycnCalls,执行结束移出。通过调用getResponseWithInterceptorChain()返回结果

5.发送异步请求,首先通过Call.enqueue(),创建一个AsyncCall对象,加入readyAsyncCalls,接下来进行判断。
创建一个临时list存储可执行call,遍历readyAsyncCalls,
如果runningAsyncCalls的数量大于最大值,退出遍历。
如果当前call的host超出最大值,跳过当前call。
如果上面两个都通过了,加入list和runningAsyncCalls。
循环结束后,遍历list,通过线程池执行call,还是要通过getResponseWithInterceptorChain()得到结果。通过接口回调,返回成功或失败结果。

6.getResponseWithInterceptorChain()(在RealCall内)
首先依次将interceptor加入集合:
OkHttpClient.interceptors()、
RetryAndFollowUpInterceptor、
BridgeInterceptor、
CacheInterceptor、
ConnectInterceptor、
NetworkInterceptor(需要forWebSocket为false,才添加,OkHttpClient.newCall()时,默认为false)
CallServerInterceptor。
通过这个集合创建一个RealInterceptorChain,调用其proceed()方法,传入请求,返回结果response

7.RealInterceptorChain
RealInterceptorChain依次调用每个Interceptor.intercept(),chain都传入一个新的RealInterceptorChain对象。
每个interceptor.intercept()都是前半部分代码对请求进行它所负责的处理,然后调用chain.proceed(),让chain把请求交给下一个interceptor进行处理。
直到最后一个CallServerInterceptor,进行真正的网络请求,对结果进行处理然后返回上一个chain.proceed(),检查完后再交给上一个interceptor.intercept(),再交给chain.proceed()。
如此循环,直到最后一个chain,将response结果返回给getResponseWithInterceptorChain(),该方法将结果返回给同步或异步的execute方法,直接返回response或者通过回调返回。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值