概念
- OkHttp 是 Square 公司開源的專注于連接效率的 HTTP 客戶端。OkHttp 提供了對 HTTP/2 和 SPDY 的支持,并提供了連接池,GZIP 壓縮和 HTTP 響應緩存功能等
- 優缺點
- 缺點:比如callback回來是在線程里面, 不能刷新UI,需要我們手動處理
- 基本用法
- 創建OkHttpClient,可以用Builder模式
- 創建Request,用Builder模式創建
-
client.newCall(request)
返回Call- 同步請求execute,直接返回
- 異步請求enquue,callBack返回(onResponse、onFailure)
整體架構(可以從以下幾個每個點深入切入)
- 接口:Call、OkHttpClient、Dispatcher、
- 流程:各個攔截器職責
- 協議:HTTP1.0、1.1、2.0(擴展gRPC),HTTPS(SSL、TLS),WebSocket
- 緩存:HTTP頭緩存、DisLruCache、cookie
- 連接:StreamAllocation(連接、流、請求)、ConnectionPoll(模式、優化)
- IO:io、nio、okio(httpCodec)
整體架構圖
Dispatcher線程池介紹
- 每個call只能被執行一次,復用則需要call#clone
- 采用Deque作為緩存,先進先出的順序執行
- 任務在try/finally中調用了finished函數,控制任務隊列的執行順序,異步執行則執行下一個請求
攔截器職責(核心重點)
-
getResponseWithInterceptorChain
責任鏈模式解耦并執行每一層的功能操作,每一層創建對應的對象,需要添加則可以自定義Interceptor,Interceptor負責攔截和分發,主要是對請求和相應的過濾處理 -
RetryAndFollowUpInterceptor
- 負責失敗重連以及重定向,失敗根據Exception(協議錯誤、中斷錯誤)的類型判斷是否可以恢復,重定向根據響應碼(code)(304)和響應頭(header),查看是否需要重定向
-
BridgeInterceptor
- 負責對Request和Response報文進行加工,請求從我們應用層傳入的數據參數類型轉化為網絡層的規定的數據類型,將網絡層返回的數據類型 轉化為 應用層數據類型,并對Htpp報文補充完整(Content-Type、Keep-Alive),加載并保存Cookie
-
CacheInterceptor
- 將請求和返回 關聯的保存到緩存中,CacheStrategy類緩存到本地使用DiskLruCache進行緩存
- Http緩存策略:
- 判斷是否過期,過期則下一步
- 有ETag標簽,If-None-Match向服務器請求,服務器決策返回,更新200,無更新304
- 有Last-Modified標簽,If-Modified-Since向服務器請求,服務器決策返回,更新200,無更新304
- 沒有向服務器請求
-
ConnectInterceptor
- 真行的開始向服務器發起器連接,通過streamAllocation的
newStream()
獲取一個流(HttpCodec,根據HTTP版本創建),HttpStream是Request和Response讀寫Socket的抽象 - newStream會根據ConnectionPoll查找是否有可復用的鏈接(當某個連接計數的次數小于限制的大小以及request的地址和緩存列表中此連接的地址完全匹配),最后創建Socket去連接
- 真行的開始向服務器發起器連接,通過streamAllocation的
-
CallServerInterceptor
- 最后連接成功會寫入請求頭,寫入請求體,讀取響應頭,讀取響應體,HttpCodec(解碼器)來處理
- 從Socket寫入讀取都是基于更高性能的okio(擴展)
- 可以擴展自定義的攔截器
- 開啟請求log、增加自定義head
流程圖
擴展(源碼修改)
- POST 緩存本地
- CookieJar修改