Android - 剖析OKHttp(1)- 构建请求

·  阅读 51

源码分析基于 3.14.4

OkHttp是什么东东呢?

  • OkHttp是一个网络请求框架,跟HttpClient、HTTPURLConnection类似;
  • OkHttp完成TCP+TLS连接,实实在在地发送Request(请求行、请求头),对Response进行处理,例如缓存、重试、重定向;
  • OkHttp底层用的是Socket;
  • 补充一点,Retrofit2对OkHttp进行了封装,OkHttp才是真正完成请求的;

OkHttp优点

  • 支持HTTP1.1以及HTTP2;
  • ConnectionPool连接池,减少同一个主机的连接延迟;
  • 默认支持GZip压缩,降低网络流量;
  • 有缓存策略,避免重复请求;
  • 失败重试以及重定向处理;

发起请求大体流程

  1. 创建OkHttpClient,配置拦截器、超时时间等;
  2. 创建Request,配置方法、请求头、请求地址等(Retrofit简化了请求的创建);
  3. 创建Call,用Request构建Call;
  4. call.enqueue加入队列,等待被调度;
  5. 解析结果(Retrofit自定解析以及线程切换)。 大家注意到了没?在步骤2、5,Retrofit做了封装处理,可以对比看下。

流程图

1.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,请求地址,对应zhuanlan.zhihu.com/api/columns…
  • 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入队;
  • 至此,任务被加入了队列,等待被调度

以上分析有不对的地方,请指出,互相学习,谢谢哦!

分类:
Android
标签:
分类:
Android
标签:
收藏成功!
已添加到「」, 点击更改