? ? 相信很多人和我一樣,對于OKhttp還是停留在只會使用卻不知道為什么這么使用的尷尬階段,敲代碼時總有一種照葫蘆畫瓢,實現了功能不報錯就溜之大吉的狀態。趁這階段有空,打算好好捋一捋這個OKhttp,像X光一樣把它徹底搞透。(此筆記為個人學習以及復習所用,如果有哪些見解錯誤,還請包含,懇請指出,蟹蟹~~)
? ? 感謝:學習(參考)資料:? 泡在網上的日子-OKHttp源碼解析? ??OKHttp3.7源碼分析? ?OKHttp完全解析
? ? 整體架構:
? ? 1.Interface:接口層,接收網絡訪問的請求
? ? 2.Protocol:協議層,處理協議邏輯
? ? 3.Connection:連接層,管理網絡連接,發送新的請求,接收服務器訪問
? ? 4.Cache:緩存層,管理本地緩存
? ? 5.InterceptChain:攔截器層,攔截網絡訪問,插入攔截邏輯
一、Interface——接口層(Call、OKHttpClient、Dispatcher):
? ? 接口層接收用戶的網絡請求(同步、異步),發起實際的網絡訪問,這里也是我們最常寫的代碼部分。
? ? OKHttpClient,我們在這里對它進行各種設置,實現各種不同形式的網絡請求,每個OKHttpClient內部都維護了屬于自己的任務隊列,連接池,Cache,攔截器等。所以在使用OkHttp作為網絡框架時應該全局共享一個OkHttpClient實例。
? ? 這里我們一般自定義一個HttpClientHelper類,在這個類中我們創建OKHttpClient這個實例:
? ? Call:描述的是一個實際的訪問請求,我們經常寫的這句:mOkHttpClient.newCall(rq).enqueue(newMyCallBack(parser) {});就是我們的實際請求,也就是說每個call都是一個網絡請求實例,那這個call到底是個啥?
? ? 官方文檔這樣說:A call is a request that has been prepared for execution. A call can be canceled. As this object represents a single request/response pair (stream),it cannot be executed twice.
? ? 查看了源代碼可以知道,實際執行過程中,OkHttp會為每一個請求創建一個RealCall,每一個RealCall內部有一個AsyncCall
這個AsyncCall它繼承了NamedRunnable,并且實現了,execute方法,也就是我們代碼最后調用的.execute()
AsyncCall繼承的NamedRunnable又繼承Runnable,所以每一個Call就是一個線程,而執行Call的過程就是執行其execute方法的過程。
? ? Dispatcher:Dispatcher是OkHttp的任務隊列,其內部維護了一個線程池,當有接收到一個Call時,Dispatcher負責在線程池中找到空閑的線程并執行其execute方法。這部分將會單獨拿一篇博客進行介紹,詳細內容可參考本系列接下來的文章。
二、Protocol——協議層:處理協議邏輯
Protocol層負責處理協議邏輯,OkHttp支持Http1/Http2/WebSocket協議,并在3.7版本中放棄了對Spdy協議,鼓勵開發者使用Http/2。
三、Connection——連接層:管理網絡連接,發送新的請求,接收服務器訪問
在連接層中有一個連接池,統一管理所有的Socket連接,當用戶新發起一個網絡請求時,OkHttp會首先從連接池中查找是否有符合要求的連接,如果有則直接通過該連接發送網絡請求;否則新創建一個網絡連接。連接層是OkHttp的核心部分,這部分會在后續單獨拿出來做筆記。
四、Cache——緩存層:管理本地緩存
Cache層負責維護請求緩存,當用戶的網絡請求在本地已有符合要求的緩存時,OkHttp會直接從緩存中返回結果,從而節省網絡開銷。后面會做詳細的筆記。
五、I/O——I/O層:實際數據讀寫實現
I/O層負責實際的數據讀寫。OkHttp的另一大有點就是其高效的I/O操作,這歸因于其高效的I/O庫okio。后面會做詳細筆記。
六、Inteceptor——攔截器層:攔截網絡訪問,插入攔截邏輯
攔截器層提供了一個類AOP接口,方便用戶可以切入到各個層面對網絡訪問進行攔截并執行相關邏輯。后面會做詳細筆記。