OkHttp深入分析——基礎(chǔ)認(rèn)知部分

一、前言

OkHttp 在 Android 網(wǎng)絡(luò)框架這一塊的地位已經(jīng)不言而喻了,尤其從 Android 4.4 之后,系統(tǒng)已經(jīng)拋棄了原生的 HttpUrlConnection 的內(nèi)部實(shí)現(xiàn),轉(zhuǎn)而是封裝了 OkHttp 的實(shí)現(xiàn),HttpUrlConnection 對外只是一層接口供開發(fā)者來調(diào)用。所以現(xiàn)在不管你是使用 HttpUrlConnection 還是 Volley,其實(shí)都是在間接使用 OkHttp,說它的出現(xiàn)基本上統(tǒng)一了 Android 的 Http 網(wǎng)絡(luò)框架真的一點(diǎn)也不為過。

二、官文解讀

1.概覽

用官網(wǎng)的話來說,OkHttp 是一個用于進(jìn)行 Http / Http2 通信的客戶端,并且同時適用于 Android 和 Java。

當(dāng)然,其還是一個非常強(qiáng)大而高效的網(wǎng)絡(luò)框架,其主要特點(diǎn)在于:

  • 對于同一個主機(jī)的所有請求,允許其在 Http / Http 2 上共享同一個套接字,這就避免了重復(fù)的 TCP 連接帶來的 3 步握手的時間。
  • 對于 Http 協(xié)議,其支持連接池用于減少請求延遲。
  • 數(shù)據(jù)都使用了 gzip 壓縮傳輸,從而減小網(wǎng)絡(luò)傳輸 size 的大小。
  • 對響應(yīng)進(jìn)行緩存,避免緩存有效期內(nèi)重復(fù)的網(wǎng)絡(luò)請求。
  • 弱網(wǎng)情況下,在連接失敗后,OkHttp 會自動進(jìn)行重試,特別是有備用地址時還會通過備用地址進(jìn)行連接。而安全上,其支持新一代的 TLS 功能,SNI 和 ALPN,如果服務(wù)器不支持的話則會主動降級到 TLS 1.0。

OkHttp的使用是很簡單的,它在 request/reponse API 上采用了鏈?zhǔn)?Builder 的設(shè)計模式,使得它具備一旦構(gòu)建便不可修改性。

最后,還提到它支持同步和異步請求。其實(shí)網(wǎng)絡(luò)請求的實(shí)現(xiàn)原理上也是一次 I/O 通信,并且大多還是同步的 I/O。早前我們直接用 HttpUrlConnection 進(jìn)行通信時根本不區(qū)分什么同步和異步,只是迫于 Android 的強(qiáng)制管理機(jī)制,要求網(wǎng)絡(luò)通信不能放在 "main thread" 中進(jìn)行,否則就報 crash,我們不得已才把網(wǎng)絡(luò)請求這一段代碼放到了子線程運(yùn)行,最后再通過 Handler 把結(jié)果返回到主線程。所以這里說的同步和異步主要也是說實(shí)現(xiàn)了同步和異步的封裝。當(dāng)然,我們進(jìn)行同步調(diào)用時,也還是不能在 "main thread" 中進(jìn)行。

2.例程

Get 請求

// 構(gòu)建 OkHttpClient 實(shí)例
OkHttpClient client = new OkHttpClient();

String run(String url) throws IOException {
  // 通過鏈?zhǔn)?Builder 設(shè)計提供的 Builder 構(gòu)建 Request
  Request request = new Request.Builder()
      .url(url)
      .build();
  // 以下是發(fā)起一個同步請求,Response 為接收的響應(yīng)結(jié)果
  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");
// 構(gòu)建 OkHttpClient 實(shí)例
OkHttpClient client = new OkHttpClient();

String post(String url, String json) throws IOException {
  // 構(gòu)建 Body
  RequestBody body = RequestBody.create(JSON, json);
 // 構(gòu)建 Request,對于 post 請求,除了設(shè)置 url 還需要設(shè)置 body
  Request request = new Request.Builder()
      .url(url)
      .post(body)
      .build();
 // 執(zhí)行一個同步的請求,響應(yīng)結(jié)果在 Response 中
  Response response = client.newCall(request).execute();
  return response.body().string();
}

sample 中的請求都是同步的,其對應(yīng)的異步請求為 client.newCall(request).enqueue(callback)。

3. 使用 gradle 中集成

這個就 so easy 了

compile 'com.squareup.okhttp3:okhttp:3.12.0'

三、工程概述

當(dāng)我們 clone 下 OkHttp 的 github 倉庫下來,會發(fā)現(xiàn)其里面含有非常多的小工程,這其實(shí)是一個大的 maven 工程。如果要工程化的管理以及調(diào)試,建議用 IntelliJ IDEA 或者 Eclipse 打開工程,而不要用 Android Studio 打開,最后得到的效果如下圖。如果打開的下圖這個樣子,你就可以進(jìn)行愉快的代碼調(diào)式了。當(dāng)然手頭最好還是準(zhǔn)備一個襯手的抓包工具,如 charles,fiddler 或者 更牛逼的 Wireshark。

image.png

從上圖看 OKHttp 的核心實(shí)現(xiàn)庫就是 okhttp 工程。作為一個優(yōu)秀的框架,一定不是孤立地存在的,還有它身邊的輔助工程,demo 工程等等。如下是整個工程模塊的分類及簡要說明。

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

四、總結(jié)

基礎(chǔ)認(rèn)知部分主要是熟悉了 OkHttp 的官網(wǎng)以及 OkHttp 源碼的整個工程。通過對整個工程的了解,其主要目的是建立一起一個全局觀。所謂站的高看的遠(yuǎn),有了全局觀之后使得我們深入到某個細(xì)節(jié)之后不致于感到迷惘。

最后,感謝你能讀到并讀完此文章。受限于作者水平有限,如果分析的過程中存在錯誤或者疑問都?xì)g迎留言討論。如果我的分享能夠幫助到你,還請記得幫忙點(diǎn)個贊吧,謝謝。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容