美文网首页okhttp程序员Android知识
OKhttp源码学习(二)—— OkHttpClient

OKhttp源码学习(二)—— OkHttpClient

作者: 逗哥笔记 | 来源:发表于2017-04-19 07:46 被阅读348次

    OkHttpClient 解剖

    源码地址:https://github.com/square/okhttp

    上一篇对整体的流程,有了窥探,这次就对另外一个重要的类进行学习分析——OkHttpCilent。

    OkHttpClient结构上比较简单,使用了Bulider模式来进行构建。

    这个类大体分了三部分:

    1. 提供内部使用的静态块;
    2. 提供给外部调用读取信息的方法,以及实现了某些接口,如之前的说到的newCall;
    3. Builder,构建相应的后续需要的变量等。(重点)

    静态块

    通过代码注析的方式,对每个方法进行了解学习。参考中文注析。

    提供的方法都是给内部使用。

      static {
        Internal.instance = new Internal() {
     
     //提供静态方法对头部信息进行处理
     @Override public void addLenient(Headers.Builder builder, String line) {
        builder.addLenient(line);
     }
    
      @Override public void addLenient(Headers.Builder builder, String name, String value) {
        builder.addLenient(name, value);
      }
      //写入缓存(响应数据缓存)
      @Override public void setCache(OkHttpClient.Builder builder, InternalCache internalCache) {
        builder.setInternalCache(internalCache);
      }
      
      //把连接变成空闲状态
      @Override public boolean connectionBecameIdle(
          ConnectionPool pool, RealConnection connection) {
        return pool.connectionBecameIdle(connection);
      }
    
      //从缓存中获取有效的连接, 从内存的ConnectiongPool中的Deque读取
      @Override public RealConnection get(ConnectionPool pool, Address address,
          StreamAllocation streamAllocation, Route route) {
        return pool.get(address, streamAllocation, route);
      }
      
      //对地址进行校验
      @Override public boolean equalsNonHost(Address a, Address b) {
        return a.equalsNonHost(b);
      }
    
      //多路复用?(待研究 StreamAllocation 类)
      @Override public Socket deduplicate(
          ConnectionPool pool, Address address, StreamAllocation streamAllocation) {
        return pool.deduplicate(address, streamAllocation);
      }
    
      //把连接添加到连接池当中,缓存起来
      @Override public void put(ConnectionPool pool, RealConnection connection) {
        pool.put(connection);
      }
      
      //获取连接池里面的连接,可以有效剔除黑名单的线路,用于优化连接效果。
      @Override public RouteDatabase routeDatabase(ConnectionPool connectionPool) {
        return connectionPool.routeDatabase;
      }
    
      //获取response 的 code
      @Override public int code(Response.Builder responseBuilder) {
        return responseBuilder.code;
      }
      
      //sslSocket 的连接协议,规范
      @Override
      public void apply(ConnectionSpec tlsConfiguration, SSLSocket sslSocket, boolean isFallback) {
        tlsConfiguration.apply(sslSocket, isFallback);
      }
    
      //检查 Url 正确性,可用性
      @Override public HttpUrl getHttpUrlChecked(String url)
          throws MalformedURLException, UnknownHostException {
        return HttpUrl.getChecked(url);
      }
      
      //获取到的 StreamAllocation(待研究) ,主要处理 Connections,Streams, Calls之间的关系
      @Override public StreamAllocation streamAllocation(Call call) {
        return ((RealCall) call).streamAllocation();
      }
      
      //新建web 相关的 Call
      @Override public Call newWebSocketCall(OkHttpClient client, Request originalRequest) {
        return new RealCall(client, originalRequest, true);
      }
    };
    }
    

    提供给外部调用的方法

    略(提供的方法,大多都是获取或者设置后面Bulider中变量。此处不做过多的解析)

    Builder

    在Builder里面,你会发现很多的变量,而这些变量都是可以提供给你设置的,提供给后面逻辑调用的。

    下面是变量:

    Dispatcher dispatcher;
    Proxy proxy;
    List<Protocol> protocols;
    List<ConnectionSpec> connectionSpecs;
    final List<Interceptor> interceptors = new ArrayList<>();
    final List<Interceptor> networkInterceptors = new ArrayList<>();
    ProxySelector proxySelector;
    CookieJar cookieJar;
    Cache cache;
    InternalCache internalCache;
    SocketFactory socketFactory;
    SSLSocketFactory sslSocketFactory;
    CertificateChainCleaner certificateChainCleaner;
    HostnameVerifier hostnameVerifier;
    CertificatePinner certificatePinner;
    Authenticator proxyAuthenticator;
    Authenticator authenticator;
    ConnectionPool connectionPool;
    Dns dns;
    boolean followSslRedirects;
    boolean followRedirects;
    boolean retryOnConnectionFailure;
    int connectTimeout;
    int readTimeout;
    int writeTimeout;
    int pingInterval;
    

    设置的默认数据:

    public Builder() {
      dispatcher = new Dispatcher(); 
      protocols = DEFAULT_PROTOCOLS;
      connectionSpecs = DEFAULT_CONNECTION_SPECS;
      proxySelector = ProxySelector.getDefault();
      cookieJar = CookieJar.NO_COOKIES;
      socketFactory = SocketFactory.getDefault();
      hostnameVerifier = OkHostnameVerifier.INSTANCE;
      certificatePinner = CertificatePinner.DEFAULT;
      proxyAuthenticator = Authenticator.NONE;
      authenticator = Authenticator.NONE;
      connectionPool = new ConnectionPool();
      dns = Dns.SYSTEM;
      followSslRedirects = true;
      followRedirects = true;
      retryOnConnectionFailure = true;
      connectTimeout = 10_000;
      readTimeout = 10_000;
      writeTimeout = 10_000;
      pingInterval = 0;
    }
    

    1. Dispatcher, 分发请求,内部是有一个ThreadPoolExecutor

    2. Proxy, 代理连接,分三种类型直接(DIRECT)、Http(http)、SOCKS。

    3. ProxySelector,线路选择器,对应Okhttp的一大特点,自行线路选择,找到合适的连接

    4. Cache, 真正的缓存实现

    5. SSLSocketFactory, Https的支持

    6. ConnectionPool, 连接池

    7. Dns,dns解析(Java实现)

    8. 其他,如超时时间等


    总结:
    OkhttpClient 类以Bulider的模式,构建了相关的数据变量,提供后面使用。内部结构比较简单,主要还是初始化每个变量提供给后面的使用。在后面的学习分析中,你会发现这个okHttpClient会无处不在,所以这里提前对其进行学习分析。

    系列:
    OKhttp源码学习(一)—— 基本请求流程
    OKhttp源码学习(三)—— Request, RealCall
    OKhttp源码学习(四)——RetryAndFollowUpInterceptor拦截器分析
    OKhttp源码学习(五)—— BridgeInterceptor
    OKhttp源码学习(六)—— CacheInterceptor拦截器
    OKhttp源码学习(七)—— ConnectInterceptor拦截器
    OKhttp源码学习(八)——CallServerInterceptor拦截器
    OKhttp源码学习(九)—— 任务管理(Dispatcher)

    相关文章

      网友评论

        本文标题:OKhttp源码学习(二)—— OkHttpClient

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