1. 程式人生 > >OkHttp 原始碼解析(1)

OkHttp 原始碼解析(1)

專案用到OkHttp,準備研究研究(OkHttp現在很火啊,Retrofit使用OkHttp,Volley支援替換底層http棧為OkHttp,甚至Google的最新原始碼裡,都用起了OkHttp,替換了原來用的HttpClient)。

OkHttp在網路有問題的時候表現很好:

  • 它會靜默從常見的連線問題中恢復。

  • 如果你的服務有多個IP地址對應,OkHttp會在首次連線失敗的時候嘗試其他地址。

  • OkHttp使用現代的TLS features (SNI, ALPN) 來初始化連線, 並在握手失敗的時候倒回到TLS 1.0。

具體如何使用就不囉嗦了,網上很多教程,直接進原始碼

OkHttpClient

  • 請求的工廠,用它可以傳送Http請求和就收返回資訊。主要是Http相關那些東西的配置。

  • 初始化兩個陣列

  private static final List<Protocol> DEFAULT_PROTOCOLS = Util.immutableList(
      Protocol.HTTP_2, Protocol.HTTP_1_1);
  private static final List<ConnectionSpec> DEFAULT_CONNECTION_SPECS = Util.immutableList(
      ConnectionSpec.MODERN_TLS, ConnectionSpec.COMPATIBLE_TLS, ConnectionSpec.CLEARTEXT);
  • 初始化Intelnal單例,提供給各處使用
  static {
        Internal.instance = new Internal() {
            // 實現各個抽象方法
        }
  }
  • 懶載入
private static SSLSocketFactory defaultSslSocketFactory;
  • 多個IP時候的選擇策略
private final RouteDatabase routeDatabase;
  • 非同步請求執行時候的策略,用到了ExecutorService作執行緒池,預設建立的是core 0,max Integer.MAX_VALUE,keep alive 60秒的執行緒池
private Dispatcher dispatcher;
  • 代理,分為DIRECT(直連無代理)、HTTP和SOCKS
private Proxy proxy;   
  • 攔截器 - 在Response正式返回前處理資料,比如Gzip解壓
private final List<Interceptor> interceptors = new ArrayList<>();
  • 這個網路攔截器可就牛逼了。。。相較前面那個發生地更早,在HttpEngine的readResponse中被呼叫
    可以做諸如CheckHandshake初始化的時候加進去了一個握手的攔截器去檢查是否在黑名單;LoggingInterceptors則加了一個log的攔截器,輸出請求和response的資訊;Progress加了個包裝response的攔截器,來增加progress功能;RewriteResponseCacheControl直接重寫server的cache控制頭
private final List<Interceptor> networkInterceptors = new ArrayList<>();
private ProxySelector proxySelector;
private CookieHandler cookieHandler;

/* Non-null if this client is caching; possibly by {@code cache}. /

  private InternalCache internalCache;
  private Cache cache;

  private SocketFactory socketFactory;
  private SSLSocketFactory sslSocketFactory;
  private HostnameVerifier hostnameVerifier;
  private CertificatePinner certificatePinner;
  private Authenticator authenticator;
  private ConnectionPool connectionPool;
  private Network network;

OkHttpClient 的一些方法

  • newCall(Request request) //Prepares the request to be executed at some point in the future.
  @Override public Call newCall(Request request) {
    return new RealCall(this, request, false /* for web socket */);
  }

為將來發送請求做準備,這樣Request、 OkHttpClient 就傳遞到了到RealCall中,我們需要做的是建立OkHttpClient、Request 通過OkHttpClient的newCall方法將OkHttpClient、Request存放到RealCall中,接著呼叫RealCall的execute執行同步請求,或者呼叫enqueue方法執行非同步操作。

接下來會繼續探究Request,Response,Call,Dispatche…