- OKhttp官方API地址 (square.github.io/okhttp/)
2.概述 高效地使用HTTP可以使你的文件加载更快,节省带宽,也就是说OKhttp是一个执行效率比较高的HTTP客户端
-
支持HTTP/2 ,当多个请求对应同一host地址时,可共用同一个socket;(http2多路复用)
-
连接池可减少请求延迟(如果HTTP/2不可用);
-
支持GZIP压缩,减少网络传输的数据大小;
-
支持Response数据缓存,避免重复网络请求;
3.OKhttp使用方法简介
4.源码解析
OKhttp分为同步请求,异步请求
4.1同步请求 同步请求请求的逻辑相对简单,我们从execute()方法查看
可以看到这Call是一个接口,定义了一个方法execute(),我们去找真正实现这个方法的地方,在前面我们通过cilent.newCall()方法执行的execute()方法,我们去看看newCall是个什么?做了那些事?
可以看到newCall()方法就是创建了一个RealCall对象,然后将前面我们通过构建者模式创建的OKHttpCilent和Request传了进去,有个点我们看到还有个参数 forWebSocket,这个参数是个啥?
forwebSocket这个其实不重要,它也是一个应用层的交互协议,像Http一样,我们都知道最初HTTP交互是客户端和服务端进行一来一回的交互,服务端是不能和客户端主动交互的(新版HTTP除外),WebSocket是服务器可以主动给客户端发消息的。我们平时开发很少用到,像那种需要频繁和服务器交互的比如股票软件,这种需要快速及时的刷新数据的。感兴趣的可以看看
接着回归正题,我们看下RealCall的excute()方法
可以看到这块主要是调用了cilent的dispatcher()方法
将call对象加入到了runningSynCalls里面,再看看这个runningSynCalls
很简单就是一个双端队列,加进去之后呢,肯定是要进行请求分发,我们回到RealCall的execute()方法,之后的方法
getResponseWithInterceptorChain()。具体对HTTP封装,结果的处理就是在这个方法里面了。我们后面再看,因为我们还要看看异步方法怎么发起请求的?
4.2异步请求
和上面一样,我们直接定位到RealCall的enqueue方法
这一块传入了一个AsyncCall对象
AsyncCall也就是一个Runable,那最终还是要调用run()方法的,不要慌,先插眼,我们后面看
接着和同步方法一样,我们看DisPatcher的enqueue方法
可以看到,将AsynCall加入到了 readyAsyncCalls 里面,然后调用 promoteAndExecute()方法
,所以我们看这个方法
readyAsyncCalls 和runningAsyncCalls都是一个双端队列,这块加锁限制了最大请求并发数,和同个主机最大连接数
对外暴露set()方法,说明可以配置,最终遍历执行asynCall.executeOn()方法,回到我们上面插眼的地方
通过线程池创建启动线程,也就到了我们刚说的AsyncCall的run方法()
总结下请求前置部分:
- 使用了构建者设计模式,封装了构建过程和细节
- 请求分为同步请求和异步请求。
- 同步请求将请求加入到了一个双端队列里面,然后开始发起请求
- 异步请求每次都会创建一个线程也就是AsynCall,然后请求先加入到准备请求队列,然后判断最大并发数,同一主机最大连接数,如果满足则开始遍历执行线程的run方法,发起请求 未完待续