Android - 剖析OKHttp(1)- 构建请求
2020-11-05 本文已影响0人
杨0612
源码分析基于 3.14.4
OkHttp是什么东东呢?
- OkHttp是一个网络请求框架,跟HttpClient、HTTPURLConnection类似;
- OkHttp完成TCP+TLS连接,实实在在地发送Request(请求行、请求头),对Response进行处理,例如缓存、重试、重定向;
- OkHttp底层用的是Socket;
- 补充一点,Retrofit2对OkHttp进行了封装,OkHttp才是真正完成请求的;
OkHttp优点
- 支持HTTP1.1以及HTTP2;
- ConnectionPool连接池,减少同一个主机的连接延迟;
- 默认支持GZip压缩,降低网络流量;
- 有缓存策略,避免重复请求;
- 失败重试以及重定向处理;
发起请求大体流程
- 创建OkHttpClient,配置拦截器、超时时间等;
- 创建Request,配置方法、请求头、请求地址等(Retrofit简化了请求的创建);
- 创建Call,用Request构建Call;
- call.enqueue加入队列,等待被调度;
- 解析结果(Retrofit自定解析以及线程切换)。
大家注意到了没?在步骤2、5,Retrofit做了封装处理,可以对比看下。
流程图
.png- 1.创建OkHttpClient
跟Retrofit类似,也是通过Build模式构建的;
//创建OkHttpClient
OkHttpClient client = new OkHttpClient.Builder().build();
//OkHttpClient类中
public class OkHttpClient implements Cloneable, Call.Factory, WebSocket.Factory {
final Dispatcher dispatcher;
final List<Protocol> protocols;
final List<ConnectionSpec> connectionSpecs;
final List<Interceptor> interceptors;
final List<Interceptor> networkInterceptors;
final ConnectionPool connectionPool;
final Dns dns;
final boolean retryOnConnectionFailure;
final int connectTimeout;
final int readTimeout;
final int writeTimeout;
以上是OkHttpClient几个比较重要属性;
- dispatcher,主要用来分发请求的,内部注意是线程池;
- protocols,支持的协议集合,分别有Protocol.HTTP_2, Protocol.HTTP_1_1;
- connectionSpecs,支持的加密算法、TLS版本,用在HTTPS建立连接;
- interceptors,自定义应用拦截器集合,例如外部传入的打印日志拦截器;
- networkInterceptors,自定义网络拦截器,CallServer拦截其执行前会回调;
- connectionPool,连接复用池,TCP连接复用池,通过请求头keep-alive属性配置;
- dns,域名解析器,域名到ip地址的解析;
- retryOnConnectionFailure,是否失败重连,默认true;
- connectTimeout、readTimeout、writeTimeout,TCP连接、读、写超时时间,默认10秒;
2. 创建Request
跟OkHttpClient类似,也是通过Build模式构建的;
//创建get请求,地址是https://zhuanlan.zhihu.com/api/columns/zhihuadmin
Request request = new Request.Builder().get().url("https://zhuanlan.zhihu.com/api/columns/zhihuadmin").build();
//Request类中
public final class Request {
final HttpUrl url;
final String method;
final Headers headers;
final @Nullable RequestBody body;
final Map<Class<?>, Object> tags;
- url,请求地址,对应https://zhuanlan.zhihu.com/api/columns/zhihuadmin;
- method,请求方法,对应GET、POST;
- headers,请求头信息,内部是一个数组;
- body,请求体,请求可以带body,例如post请求;
3. 创建Call
Call对象是通过OkHttpClient创建的;
//创建Call
Call call = client.newCall(request);//最终会调用RealCall.newRealCall
//RealCall类中
static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
RealCall call = new RealCall(client, originalRequest, forWebSocket);
return call;
}
- 这是RealCall的静态方法,方法很简单,用client以及originalRequest构建RealCall;
4.发起请求
//通过enqueue方法发起请求
call.enqueue(new Callback() {//RealCall是Call的实现类,所以调用下面的函数
@Override
public void onFailure(Call call, IOException e) {}
@Override
public void onResponse(Call call, Response response) throws IOException {}
});
//RealCall类中
@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");//1
executed = true;
}
client.dispatcher().enqueue(new AsyncCall(responseCallback));//2
}
- 注释1:确保同一个Call只能执行一次;
- 注释2:调用分发器将Call封装成AsyncCall入队;
- 至此,任务被加入了队列,等待被调度。
以上分析有不对的地方,请指出,互相学习,谢谢哦!