从零开始的 OkHttp
OkHttp
源码流程
答案参考自:
基本流程
- 创建 OkHttpClient 对象
- 创建 Request 对象
- 创建 Call 对象
- 同步请求调用 call.execute();异步请求调用 call.enqueue()。
OkHttp
线程池
答案参考自:
OkHttp
的异步请求是基于其内部的默认的线程池实现的。
而默认的线程池是在 Dispatcher
被实例化的。
1 |
|
该线程池的核心线程数为 0,线程池最有能容纳 Integer.MAX_VALUE
个线程,且线程的空闲存活时间为 60s(可以理解为 OkHttp 随时可以创建新的线程来满足需要。可以保证网络的 I/O 任务有线程来处理,不被阻塞)。
重点是使用的阻塞队列为 SynchronousQueue,参考:
[java1.8源码笔记]SynchronousQueue详解 | LuoMing’s Blog (luoming1224.github.io)
OkHttp
拦截器
getResponseWithInterceptorChain()
1 |
|
可以看到,首先,他会将客户端的 interceptors
添加到 List
当中,接着,再添加 okhttp 里面的 interceptor
,然后构建了一个 RealInterceptorChain
对象,并将我们的 List<Interceptor>
作为成员变量,最后调用 RealInterceptorChain
的 proceed
方法。
其中,client.interceptors()
为我们自己添加的请求拦截器,通常是做一些添加统一的 token 之类操作。
RetryAndFollowUpInterceptor 拦截器
- RetryAndFollowUpInterceptor 此拦截器顾名思义就是主要负责失败重连工作,但是并不是所有的网络请求都会进行失败重连的,在此拦截器内部会进行网络请求的异常检测和响应码的判断,如果都在限制范围内,那么就可以进行失败重连。
- 一个循环来不停的获取response。每循环一次都会获取下一个request,如果没有,则返回response,退出循环。而获取下一个request的逻辑,是根据上一个response返回的状态码,分别作处理。
桥接拦截器
- 请求从应用层数据类型类型转化为网络调用层的数据类型。
- 将网络层返回的数据类型 转化为 应用层数据类型。
CacheInterceptor 拦截器
- 作用:将HTPTP和HTTPS的网络返回数据缓存到文件系统中,以便在服务端数据没发生变化的情况下复用,节省时间和带宽;
连接拦截器 和 最后的请求服务器的拦截器
这两个连接器基本上完成了最后发起网络请求的工作。
addInterceptor
和 addNetworkInterceptor
区别
答案参考自:
从上文构造拦截器链的过程,可以看到,通过 addInterceptor()
方法添加的拦截器是放在最前面的。
而通过 addNetworkInterceptor()
方法添加的网络拦截器,则是在非 WebSocket 请求时,添加在 ConnectInterceptor
和 CallServerInterceptor
之间的。
addInterceptor(应用拦截器)
- 不需要担心中间过程的响应,如重定向和重试.
- 总是只调用一次,即使 HTTP 响应是从缓存中获取.
- 观察应用程序的初衷. 不关心 OkHttp 注入的头信息如:
If-None-Match
. - 允许短路而不调用 Chain#proceed,即中止调用.
- 允许重试,使 Chain#proceed 调用多次.
addNetworkInterceptor(网络拦截器)
- 能够操作中间过程的响应,如重定向和重试.
- 当网络短路而返回缓存响应时不被调用.
- 只观察在网络上传输的数据.
- 携带请求来访问连接.
OkHttp
责任链模式
proceed()
proceed
v.
继续做(或从事、进行);接着做;继而做;行进
1 |
|
proceed 方法也很简单,proceed方法每次从拦截器列表中取出拦截器,并调用 interceptor.intercept(next)。
熟悉 Okhttp 的应该都知道,我们在 addInterceptor 创建 Interceptor 实例,最终都会调用 chain.proceed(Request request),从而形成一种链式调用。这种便是责任链设计模式。
1 |
|
而 OkHttp 是怎样结束循环调用的,这是因为最后一个拦截器 CallServerInterceptor 并没有调用 chain.proceed(request),所以能够结束循环调用。
OkHttp
缓存怎么处理
答案参考自: