一、前言
OkHttp 在 Android 網(wǎng)絡框架這一塊的地位已經(jīng)不言而喻了捎谨,尤其從 Android 4.4 之后,系統(tǒng)已經(jīng)拋棄了原生的 HttpUrlConnection 的內(nèi)部實現(xiàn),轉(zhuǎn)而是封裝了 OkHttp 的實現(xiàn)她按,HttpUrlConnection 對外只是一層接口供開發(fā)者來調(diào)用阔挠。所以現(xiàn)在不管你是使用 HttpUrlConnection 還是 Volley飘庄,其實都是在間接使用 OkHttp,說它的出現(xiàn)基本上統(tǒng)一了 Android 的 Http 網(wǎng)絡框架真的一點也不為過购撼。
二跪削、官文解讀
1.概覽
用官網(wǎng)的話來說,OkHttp 是一個用于進行 Http / Http2 通信的客戶端迂求,并且同時適用于 Android 和 Java碾盐。
當然,其還是一個非常強大而高效的網(wǎng)絡框架揩局,其主要特點在于:
- 對于同一個主機的所有請求毫玖,允許其在 Http / Http 2 上共享同一個套接字,這就避免了重復的 TCP 連接帶來的 3 步握手的時間凌盯。
- 對于 Http 協(xié)議付枫,其支持連接池用于減少請求延遲。
- 數(shù)據(jù)都使用了 gzip 壓縮傳輸驰怎,從而減小網(wǎng)絡傳輸 size 的大小阐滩。
- 對響應進行緩存,避免緩存有效期內(nèi)重復的網(wǎng)絡請求县忌。
- 弱網(wǎng)情況下掂榔,在連接失敗后,OkHttp 會自動進行重試症杏,特別是有備用地址時還會通過備用地址進行連接装获。而安全上,其支持新一代的 TLS 功能鸳慈,SNI 和 ALPN饱溢,如果服務器不支持的話則會主動降級到 TLS 1.0。
OkHttp的使用是很簡單的走芋,它在 request/reponse API 上采用了鏈式 Builder 的設計模式绩郎,使得它具備一旦構(gòu)建便不可修改性。
最后翁逞,還提到它支持同步和異步請求肋杖。其實網(wǎng)絡請求的實現(xiàn)原理上也是一次 I/O 通信,并且大多還是同步的 I/O挖函。早前我們直接用 HttpUrlConnection 進行通信時根本不區(qū)分什么同步和異步状植,只是迫于 Android 的強制管理機制,要求網(wǎng)絡通信不能放在 "main thread" 中進行,否則就報 crash津畸,我們不得已才把網(wǎng)絡請求這一段代碼放到了子線程運行振定,最后再通過 Handler 把結(jié)果返回到主線程。所以這里說的同步和異步主要也是說實現(xiàn)了同步和異步的封裝肉拓。當然后频,我們進行同步調(diào)用時,也還是不能在 "main thread" 中進行暖途。
2.例程
Get 請求
// 構(gòu)建 OkHttpClient 實例
OkHttpClient client = new OkHttpClient();
String run(String url) throws IOException {
// 通過鏈式 Builder 設計提供的 Builder 構(gòu)建 Request
Request request = new Request.Builder()
.url(url)
.build();
// 以下是發(fā)起一個同步請求卑惜,Response 為接收的響應結(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 實例
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 請求露久,除了設置 url 還需要設置 body
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
// 執(zhí)行一個同步的請求,響應結(jié)果在 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'
三、工程概述
當我們 clone 下 OkHttp 的 github 倉庫下來纸巷,會發(fā)現(xiàn)其里面含有非常多的小工程镇草,這其實是一個大的 maven 工程眶痰。如果要工程化的管理以及調(diào)試瘤旨,建議用 IntelliJ IDEA 或者 Eclipse 打開工程,而不要用 Android Studio 打開竖伯,最后得到的效果如下圖存哲。如果打開的下圖這個樣子,你就可以進行愉快的代碼調(diào)式了七婴。當然手頭最好還是準備一個襯手的抓包工具祟偷,如 charles,fiddler 或者 更牛逼的 Wireshark。
從上圖看 OKHttp 的核心實現(xiàn)庫就是 okhttp 工程打厘。作為一個優(yōu)秀的框架修肠,一定不是孤立地存在的,還有它身邊的輔助工程户盯,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 協(xié)議 |
8 | okhttp-andorid-support | 增強 Android 的支持 |
9 | okhttp-apache | 封裝了 OkHttp 版本的 apache HttpClient 實現(xiàn)族奢,未來版本中會被移除 |
10 | okhttp-tests | 單元測試 |
11 | okhttp-urlconnection | 封裝了 OkHttp 版本的 HttpUrlConnection,未來版本中會被移除 |
12 | okhttp-tls | 簡化 tls 使用的 API丹鸿,尤其自簽名證書 |
13 | okhttp-see | 實驗性的用于支持服務器發(fā)送的事件歹鱼。API不穩(wěn)定,可能隨時更改卜高。 |
14 | okhttp-logging-interceptor | 典型的 interceptor 用例 |
15 | bom | 目前還只是一個空模塊 |
16 | websites | okhttp 站點頁面 |
17 | okhttp | okhttp 核心庫的實現(xiàn) |
四弥姻、總結(jié)
基礎認知部分主要是熟悉了 OkHttp 的官網(wǎng)以及 OkHttp 源碼的整個工程。通過對整個工程的了解掺涛,其主要目的是建立一起一個全局觀庭敦。所謂站的高看的遠,有了全局觀之后使得我們深入到某個細節(jié)之后不致于感到迷惘薪缆。
最后秧廉,感謝你能讀到并讀完此文章。受限于作者水平有限拣帽,如果分析的過程中存在錯誤或者疑問都歡迎留言討論疼电。如果我的分享能夠幫助到你,還請記得幫忙點個贊吧减拭,謝謝蔽豺。