源码分析
https://www.jianshu.com/p/37e26f4ea57b
https://juejin.im/post/6844903586464268295#heading-19
为什么要在项目中使用这个库?
OkHttp 提供了对最新的 HTTP 协议版本 HTTP/2 和 SPDY 的支持,这使得对同一个主机发出的所有请求都可以共享相同的套接字连接。
如果 HTTP/2 和 SPDY 不可用,OkHttp 会使用连接池来复用连接以提高效率。
OkHttp 提供了对 GZIP 的默认支持来降低传输内容的大小。
OkHttp 也提供了对 HTTP 响应的缓存机制,可以避免不必要的网络请求。
当网络出现问题时,OkHttp 会自动重试一个主机的多个 IP 地址。
使用场景?
get、post请求、上传文件、上传表单等等
缺点
缺点:使用的时候仍然需要自己再做一层封装
这个库的核心实现原理是什么?如果让你实现这个库的某些核心功能,你会考虑怎么去实现?
OkHttp内部的请求流程:使用OkHttp会在请求的时候初始化一个Call的实例,然后执行它的execute()方法或enqueue()方法,内部最后都会执行到getResponseWithInterceptorChain()方法,这个方法里面通过拦截器组成的责任链,依次经过用户自定义普通拦截器、重试拦截器、桥接拦截器、缓存拦截器、连接拦截器和用户自定义网络拦截器以及访问服务器拦截器等拦截处理过程,来获取到一个响应并交给用户。其中,除了OKHttp的内部请求流程这点之外,缓存和连接这两部分内容也是两个很重要的点,掌握了这3点就说明你理解了OkHttp
各个拦截器的作用:
interceptors:用户自定义拦截器
retryAndFollowUpInterceptor:负责失败重试以及重定向
BridgeInterceptor:请求时,对必要的Header进行一些添加,接收响应时,移除必要的Header
CacheInterceptor:负责读取缓存直接返回(根据请求的信息和缓存的响应的信息来判断是否存在缓存可用)、更新缓存
ConnectInterceptor:负责和服务器建立连接
ConnectionPool:
1、判断连接是否可用,不可用则从ConnectionPool获取连接,ConnectionPool无连接,创建新连接,握手,放入ConnectionPool。
2、它是一个Deque,add添加Connection,使用线程池负责定时清理缓存。
3、使用连接复用省去了进行 TCP 和 TLS 握手的一个过程。
networkInterceptors:用户定义网络拦截器
CallServerInterceptor:负责向服务器发送请求数据、从服务器读取响应数据
你从这个库中学到什么有价值的或者说可借鉴的设计思想?
使用责任链模式实现拦截器的分层设计,每一个拦截器对应一个功能,充分实现了功能解耦,易维护
Okhttp的子系统层级结构图如下所示:
网络配置层–OkhttpClient–OkHttpClient.Builder
重定向层–RetryAndFollowUpInterceptor–StreamAllocation
Header拼接层–Request–Headers
Http缓存层–Cache–DisLruCache
网络连接层–RealConnection,ConnectionPool,Platform,socket,SSLSocket,Proxy,Route,RouteSelector,RouteDatabase
数据响应层–Response,Http1Codec,Http2Codec,Http2Connection,Buffer,Sink
网络配置层:利用Builder模式配置各种参数,例如:超时时间、拦截器等,这些参数都会由Okhttp分发给各个需要的子系统。
重定向层:负责重定向。
Header拼接层:负责把用户构造的请求转换为发送给服务器的请求,把服务器返回的响应转换为对用户友好的响应。
HTTP缓存层:负责读取缓存以及更新缓存。
连接层:连接层是一个比较复杂的层级,它实现了网络协议、内部的拦截器、安全性认证,连接与连接池等功能,但这一层还没有发起真正的连接,它只是做了连接器一些参数的处理。
数据响应层:负责从服务器读取响应的数据。
在整个Okhttp的系统中,我们还要理解以下几个关键角色:
OkHttpClient:通信的客户端,用来统一管理发起请求与解析响应。
Call:Call是一个接口,它是HTTP请求的抽象描述,具体实现类是RealCall,它由CallFactory创建。
Request:请求,封装请求的具体信息,例如:url、header等。
RequestBody:请求体,用来提交流、表单等请求信息。
Response:HTTP请求的响应,获取响应信息,例如:响应header等。
ResponseBody:HTTP请求的响应体,被读取一次以后就会关闭,所以我们重复调用responseBody.string()获取请求结果是会报错的。
Interceptor:Interceptor是请求拦截器,负责拦截并处理请求,它将网络请求、缓存、透明压缩等功能都统一起来,每个功能都是一个Interceptor,所有的Interceptor最 终连接成一个Interceptor.Chain。典型的责任链模式实现。
StreamAllocation:用来控制Connections与Streas的资源分配与释放。
RouteSelector:选择路线与自动重连。
RouteDatabase:记录连接失败的Route黑名单