美文网首页
Android - 剖析OKHttp(1)- 构建请求

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

作者: 杨0612 | 来源:发表于2020-11-05 16:43 被阅读0次

    源码分析基于 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做了封装处理,可以对比看下。

    流程图

    .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;
    

    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 - 剖析OKHttp(1)- 构建请求

          本文链接:https://www.haomeiwen.com/subject/ndqavktx.html