Okhttp3 總結研究 (面試)

2021-08-17 21:59:07 字數 4146 閱讀 2696

android okhttp(三)原始碼解析: (這是我第一篇看的okhttp的原始碼解析,根據這篇文章和自己檢視okhtttp 原始碼,看okhttp內部,這篇文章大概講清楚okhttp 內部構造,雖然有些語言表達上的錯誤,這篇也是針對okhttp的.建議可以先看這篇,先了解大概)

okhttp原始碼解析: (這是第二篇,也是最近在看的一篇,大神分析的比較全,也比較準確,詳細解析的okhttp3)

okhttp3原始碼分析[綜述]

: (這篇是將原始碼分析,拆成了5個部分,分析也很很好,適合看)

android okhttp3 建立socket的底層實現追蹤 :(這篇描述了okhttp3 socket底層的實現)

okhttp3原始碼和設計模式

(這篇從設計模式的角度分析okhttp3)

okhttp3對realcall的注釋及上篇是dispatcher

okhttp3: 從以下方面總結

為什麼okhttp3 好用呢?

okhttp是乙個精巧的網路請求庫,有如下特性: 

1)支援http2,對一台機器的所有請求共享同乙個socket

2)內建連線池,支援連線復用,減少延遲

3)支援透明的gzip壓縮響應體

4)通過快取避免重複的請求

5)請求失敗時自動重試主機的其他ip,自動重定向

6)好用的api

實現網路請求方法:

okhttp3的最底層是socket,而不是urlconnection,它通過platform的class.forname()反射獲得當前runtime使用的socket庫

socket發起網路請求的流程一般是:

(1). 建立socket物件;

(2). 連線到目標網路;

(3). 進行輸入輸出流操作。

(1)(2)的實現,封裝在connection介面中,具體的實現類是realconnection。

(3)是通過stream介面來實現,根據不同的網路協議,有http1xstream和http2xstream兩個實現類

由於建立網路連線的時間較久(如果是http的話,需要進行三次握手),而請求經常是頻繁的碎片化的,所以為了提高網路連線的效率,okhttp3實現了網路連線復用

運用到的設計模式:

單例模式:(建議用單例模式建立okhttpclient)okhttpclient, 可以通過 new okhttpclient() 或 new okhttpclient.builder() 來建立物件, 但是---特別注意, okhttpclient() 物件最好是共享的, 建議使用單例模式建立。 因為每個 okhttpclient 物件都管理自己獨有的執行緒池和連線池。 這一點很多同學,甚至在我經歷的團隊中就有人踩過坑, 每乙個請求都建立乙個 okhttpclient 導致記憶體爆掉

外觀模式: okhttpclient 裡面組合了很多的類物件。其實是將okhttp的很多功能模組,全部包裝進這個類中,讓這個類單獨提供對外的api,這種設計叫做外觀模式(外觀模式:隱藏系統的複雜性,並向客戶端提供了乙個客戶端可以訪問系統的介面)

builder模式: okhttpclient 比較複雜, 太多屬性, 而且客戶的組合需求多樣化, 所以okhttp使用建造者模式(build模式:使用多個簡單的物件一步一步構建成乙個複雜的物件,乙個 builder 類會一步一步構造最終的物件)

工廠方法模式:call介面提供了內部介面factory(用於將物件的建立延遲到該工廠類的子類中進行,從而實現動態的

配置,工廠方法模式。(工廠方法模式:這種型別的設計模式屬於建立型模式,它提供了一種建立物件的最佳方式。在工廠模式中,我們在建立物件時不會對客戶端暴露建立邏輯,並且是通過使用乙個共同的介面來指向新建立的物件。)

享元模式:在dispatcher的執行緒池中,所用到了享元模式,乙個不限容量的執行緒池 , 執行緒空閒時存活時間為 60 秒。執行緒池實現了物件復用,降低執行緒建立開銷,從設計模式上來講,使用了享元模式。(享元模式:嘗試重用現有的同類物件,如果未找到匹配的物件,則建立新物件,主要用於減少建立物件的數量,以減少記憶體占用和提高效能)

責任鏈模式:很明顯,在okhttp中的***模組,執行過程用到。okhttp3 的***鏈中, 內建了5個預設的***,分別用於重試、請求物件轉換、快取、鏈結、網路讀寫(責任鏈模式:為請求建立了乙個接收者物件的鏈。這種模式給予請求的型別,對請求的傳送者和接收者進行解耦。這種型別的設計模式屬於行為型模式。在這種模式中,通常每個接收者都包含對另乙個接收者的引用。如果乙個物件不能處理該請求,那麼它會把相同的請求傳給下乙個接收者,依此類推。)

策略模式:cacheinterceptor 實現了資料的選擇策略, 來自網路還是來自本地? 這個場景也是比較契合策略模式場景, cacheinterceptor 需要乙個策略提供者提供它乙個策略(錦囊), cacheinterceptor 根據這個策略去選擇走網路資料還是本地快取。

快取的策略過程:

1、 請求頭包含 "if-modified-since" 或 "if-none-match" 暫時不走快取

2、 客戶端通過 cachecontrol 指定了無快取,不走快取

3、客戶端通過 cachecontrol 指定了快取,則看快取過期時間,符合要求走快取。

4、 如果走了網路請求,響應狀態碼為 304(只有客戶端請求頭包含 "if-modified-since" 或 "if-none-match" ,伺服器資料沒變化的話會返回304狀態碼,不會返回響應內容), 表示客戶端繼續用快取。

(策略模式:乙個類的行為或其演算法可以在執行時更改。這種型別的設計模式屬於行為型模式。策略模式中,我們建立表示各種策略的物件和乙個行為隨著策略物件改變而改變的 context 物件。策略物件改變 context 物件的執行演算法。)

原始碼中用到的幾個重要的類及作用解釋:

1.okhttpclient:對外的api,okhttp的很多功能模組,全部包裝進這個類;建立分為兩種:一種是new okhttpclient()的方式,另一種是使用建造者(builder)模式 -- new okhttpclient.builder()....build()。那麼這兩種方式有什麼區別呢?

第一種:new okhttpclient(),okhttp做了很多任務作,很多我們需要的引數在這裡都獲得預設值,也就是預設值設定。

第二種:預設的設定和第一種方式相同,但是我們可以利用建造者模式單獨的設定每乙個屬性;

注意事項:okhttpclient強烈建議全域性單例使用,因為每乙個okhttpclient都有自己單獨的連線池和執行緒池,復用連線池和執行緒池能夠減少延遲、節省記憶體。

2.realcall類:

3.dispatcher類(排程器,多執行緒):儲存同步和非同步call的地方,並負責執行非同步asynccall

4.***鏈

httpengine類

:okhttp底層的實現,(還在看)

快取策略:提到快取策略,就要提到cacheinterceptor***,如下圖

cachestrategy實現快取策略,cachestrategy

執行緒池(同步,非同步):

針對非同步請求,dispatcher使用了兩個deque,乙個儲存準備執行的請求,乙個儲存正在執行的請求,為什麼要用兩個呢?因為dispatcher預設支援最大的併發請求是64個,單個host最多執行5個併發請求,如果超過,則call會先被放入到readyasynccall中,當出現空閒的執行緒時,再將readyasynccall中的執行緒移入到runningasyncalls中,執行請求。

如果正在執行的請求總數<=64 && 單個host正在執行的請求<=5,則將請求加入到runningasynccalls集合中,緊接著就是利用執行緒池執行該請求,否則就將該請求放入readyasynccalls集合中。

未完待續。

OKHttp3學習記錄

一 概述 okhttp作為時下android開發最火熱的網路請求框架,學習下還是很有必要的,記錄學習過程方便以後查詢,guthub位址在android studio中新增依賴 新增網路許可權 二 使用 主要分為這幾步 1.建立okhttpclient物件 2.建立request包括請求體,具體為引數...

OkHttp3簡單使用

複製 目前最新的穩定版可能已經不是3.11.0了,可以到官方github來檢視最新版本 github.com square okht get 預設就是get請求,可以不寫 複製 與get相比,post多了乙個請求體 requestbody 複製 string url 複製 okhttpclient ...

okhttp3學習筆記

面試使人能夠更正確的認識自己,通過這一輪的面試,我發現自己的基礎知識還是有欠缺的。而且我的記性是真不好,很多寫過的 通過很長時間的思考和摸索才做出來的效果,過不了多久都忘了,因此我決定把平時常用的,我寫專案的過程中遇到的困難,解決的方法都一一記錄下來,同時,也把平時學習新知識的筆記寫在這裡。這一篇記...