OKhttp介绍
https://square.github.io/okhttp/
由Square公司贡献的一个处理网络请求的开源项目,是目前Android使用最广泛的网络框架。从Android4.4开始HttpURLConnection的底层实现采用的是OkHttp。
- 支持HTTP/2并允许对同一主机的所有请求共享一个套接字
- 通过连接池,减少了请求延迟
- 默认通过GZip压缩数据
- 响应缓存,避免了重复请求的网络
- 请求失败自动重试主机的其他ip,自动重定向
使用方法
OKhttp请求流程
OkHttp请求过程中最少只需要接触OkHttpClient、Request、Call、Response,但是框架内部进行大量的逻辑处理。
所有的逻辑大部分集中在拦截器中,但是在进入拦截器之前还需要依靠分发器来调配请求任务。
- 分发器:内部维护队列与线程池,完成请求调配;
- 拦截器:五大默认拦截器完成整个请求过程。
分发器相关
分发器异步请求工作流程
分发器总结
对于同步请求,分发器只记录请求,用于判断IdleRunnable是否需要执行
对于异步请求,向分发器中提交请求:
1. 如何决定将请求放入ready还是running?
A: 如果当前正在请求数不小于64放入ready;如果小于64,但是已经存在同一域名主机的请求5个放入ready
2.从ready移动running的条件是什么?
A: 每个请求执行完成就会从running移除,同时进行第一步相同逻辑的判断,决定是否移动!
3.分发器线程池的工作行为?
A:无等待,最大并发
拦截器
1、重试拦截器(retryAndFollowUpInterceptor)在交出(交给下一个拦截器)之前,负责判断用户是否取消了请求;在获得了结果之后,会根据响应码判断是否需要重定向,如果满足条件那么就会重启执行所有拦截器。
2、桥接拦截器(BridgeInterceptor)在交出之前,负责将HTTP协议必备的请求头加入其中(如:Host)并添加一些默认的行为(如:GZIP压缩);在获得了结果后,调用保存cookie接口并解析GZIP数据。
3、缓存拦截器(CacheInterceptor)顾名思义,交出之前读取并判断是否使用缓存;获得结果后判断是否缓存。
4、连接拦截器(ConnectInterceptor)在交出之前,负责找到或者新建一个连接,并获得对应的socket流;在获得结果后不进行额外的处理。
5、请求服务器拦截器(CallServerInterceptor)进行真正的与服务器的通信,向服务器发送数据,解析读取的响应数据。
获得响应
在请求需要执行时,通过 getResponseWithInterceptorChain 获得请求的结果: Response
Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
List<Interceptor> interceptors = new ArrayList<>();
interceptors.addAll(client.interceptors());
interceptors.add(retryAndFollowUpInterceptor);
interceptors.add(new BridgeInterceptor(client.cookieJar()));
interceptors.add(new CacheInterceptor(client.internalCache()));
interceptors.add(new ConnectInterceptor(client));
if (!forWebSocket) {
interceptors.addAll(client.networkInterceptors());
}
interceptors.add(new CallServerInterceptor(forWebSocket));
Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0,
originalRequest, this, eventListener, client.connectTimeoutMillis(),
client.readTimeoutMillis(), client.writeTimeoutMillis());
return chain.proceed(originalRequest);
}