OkHttp深刻分析——基礎認知部分

1、前言

OkHttp 在 Android 網絡框架這一塊的地位已經不言而喻了,尤爲從 Android 4.4 以後,系統已經拋棄了原生的 HttpUrlConnection 的內部實現,轉而是封裝了 OkHttp 的實現,HttpUrlConnection 對外只是一層接口供開發者來調用。因此如今無論你是使用 HttpUrlConnection 仍是 Volley,其實都是在間接使用 OkHttp,說它的出現基本上統一了 Android 的 Http 網絡框架真的一點也不爲過。git

2、官文解讀

1.概覽

用官網的話來講,OkHttp 是一個用於進行 Http / Http2 通訊的客戶端,而且同時適用於 Android 和 Java。github

固然,其仍是一個很是強大而高效的網絡框架,其主要特色在於:web

  • 對於同一個主機的全部請求,容許其在 Http / Http 2 上共享同一個套接字,這就避免了重複的 TCP 鏈接帶來的 3 步握手的時間。
  • 對於 Http 協議,其支持鏈接池用於減小請求延遲。
  • 數據都使用了 gzip 壓縮傳輸,從而減少網絡傳輸 size 的大小。
  • 對響應進行緩存,避免緩存有效期內重複的網絡請求。
  • 弱網狀況下,在鏈接失敗後,OkHttp 會自動進行重試,特別是有備用地址時還會經過備用地址進行鏈接。而安全上,其支持新一代的 TLS 功能,SNI 和 ALPN,若是服務器不支持的話則會主動降級到 TLS 1.0。

OkHttp的使用是很簡單的,它在 request/reponse API 上採用了鏈式 Builder 的設計模式,使得它具有一旦構建便不可修改性。算法

最後,還提到它支持同步和異步請求。其實網絡請求的實現原理上也是一次 I/O 通訊,而且大多仍是同步的 I/O。早前咱們直接用 HttpUrlConnection 進行通訊時根本不區分什麼同步和異步,只是迫於 Android 的強制管理機制,要求網絡通訊不能放在 "main thread" 中進行,不然就報 crash,咱們不得已才把網絡請求這一段代碼放到了子線程運行,最後再經過 Handler 把結果返回到主線程。因此這裏說的同步和異步主要也是說實現了同步和異步的封裝。固然,咱們進行同步調用時,也仍是不能在 "main thread" 中進行。apache

2.例程

Get 請求json

// 構建 OkHttpClient 實例
OkHttpClient client = new OkHttpClient();

String run(String url) throws IOException {
  // 經過鏈式 Builder 設計提供的 Builder 構建 Request
  Request request = new Request.Builder()
      .url(url)
      .build();
  // 如下是發起一個同步請求,Response 爲接收的響應結果
  Response response = client.newCall(request).execute();
  return response.body().string();
}
複製代碼

Post 請求設計模式

// 指定 Body 的 cotent-type 爲 application/json,通常狀況下都是這個
public static final MediaType JSON
    = MediaType.parse("application/json; charset=utf-8");
// 構建 OkHttpClient 實例
OkHttpClient client = new OkHttpClient();

String post(String url, String json) throws IOException {
  // 構建 Body
  RequestBody body = RequestBody.create(JSON, json);
 // 構建 Request,對於 post 請求,除了設置 url 還須要設置 body
  Request request = new Request.Builder()
      .url(url)
      .post(body)
      .build();
 // 執行一個同步的請求,響應結果在 Response 中
  Response response = client.newCall(request).execute();
  return response.body().string();
}
複製代碼

sample 中的請求都是同步的,其對應的異步請求爲 client.newCall(request).enqueue(callback)。緩存

3. 使用 gradle 中集成

這個就 so easy 了安全

compile 'com.squareup.okhttp3:okhttp:3.12.0'
複製代碼

3、工程概述

當咱們 clone 下 OkHttp 的 github 倉庫下來,會發現其裏面含有很是多的小工程,這實際上是一個大的 maven 工程。若是要工程化的管理以及調試,建議用 IntelliJ IDEA 或者 Eclipse 打開工程,而不要用 Android Studio 打開,最後獲得的效果以下圖。若是打開的下圖這個樣子,你就能夠進行愉快的代碼調式了。固然手頭最好仍是準備一個襯手的抓包工具,如 charles,fiddler 或者 更牛逼的 Wireshark。bash

image.png

從上圖看 OKHttp 的核心實現庫就是 okhttp 工程。做爲一個優秀的框架,必定不是孤立地存在的,還有它身邊的輔助工程,demo 工程等等。以下是整個工程模塊的分類及簡要說明。

工程模塊分類圖

模塊名 說明
1 benchmark 主要用於性能測試。
2 mockwebserver mock 一個 web 服務器,方便測試。包括了 HTTP 和 HTTPS 全棧測試。
3 okhttp-dnsoverhttps 使用OkHttp在HTTPS上進行DNS實驗
4 okhttp-hpacktests hpack 測試,hapck 即頭部壓縮算法,主要應用在 http2 上
5 okhttp-testing-support 測試支持模塊
6 sampls 例程
7 okcurl okhttp 版本的 curl,能夠測試整個 okhttp 庫,包括了 http2 協議
8 okhttp-andorid-support 加強 Android 的支持
9 okhttp-apache 封裝了 OkHttp 版本的 apache HttpClient 實現,將來版本中會被移除
10 okhttp-tests 單元測試
11 okhttp-urlconnection 封裝了 OkHttp 版本的 HttpUrlConnection,將來版本中會被移除
12 okhttp-tls 簡化 tls 使用的 API,尤爲自簽名證書
13 okhttp-see 實驗性的用於支持服務器發送的事件。API不穩定,可能隨時更改。
14 okhttp-logging-interceptor 典型的 interceptor 用例
15 bom 目前還只是一個空模塊
16 websites okhttp 站點頁面
17 okhttp okhttp 核心庫的實現

4、總結

基礎認知部分主要是熟悉了 OkHttp 的官網以及 OkHttp 源碼的整個工程。經過對整個工程的瞭解,其主要目的是創建一塊兒一個全局觀。所謂站的高看的遠,有了全局觀以後使得咱們深刻到某個細節以後不致於感到迷惘。

最後,感謝你能讀到並讀完此文章。受限於做者水平有限,若是分析的過程當中存在錯誤或者疑問都歡迎留言討論。若是個人分享可以幫助到你,還請記得幫忙點個贊吧,謝謝。

相關文章
相關標籤/搜索