OkHttp3分析

OkHttp3是一個精巧的網絡請求庫,有如下特性

  • 1)支持HTTP2,對一臺機器的所有請求共享同一個socket
  • 2)內置連接池,支持連接複用,減少延遲
  • 3)支持透明的gzip壓縮響應體
  • 4)通過緩存避免重複的請求
  • 5)請求失敗時自動重試主機其他的ip,自動重定向
  • 6)好用的API

OkHttp請求劃分爲三個階段

  • 1 OKHttpClient+Request構造RealCall
  • 2 RealCall直接同步執行或者進入異步隊列,同一有Dispatcher分發
  • 3 通過Interceptor的責任鏈,層層調用,最後獲取Response

實現網絡請求方法

OkHttp3的最底層是Socket,而不是URLConnection,它通過Platfrom的Class.forName()反射獲得當前Runtime使用的socket庫

Socket發起網絡請求的一般流程是:

  • (1) 創建socket對象
  • (2) 連接到目標網絡
  • (3) 進行輸入輸出流操作

(1)(2)的實現,封裝在connection接口中,具體的實現類是RealConnection。

(3) 通過stream接口來實現,根據不同的網絡協議,有Http1XStream和Http2xStream兩個實現類,由於創建網絡連接的時間較久(如果是HTTP的話,需要進行三次握手),而請求經常是頻繁的碎片化的,所以爲了提高網絡連接的效率,OkHttp3實現了網絡連接的複用。

運用到的設計模式

  • 1 單例模式:
  • 2 外觀模式:OkHttpClient裏面組合了很多類對象。其實是將OKHttp的很多功能模塊,全部包裝進這個類中,讓這個類單獨提供對外的API,這種設計叫做外觀模式(外觀模式:隱藏系統的複雜性,並向客戶端提供一個客戶端可以訪問系統的接口)
  • 3 Builder模式:OkHttpClient比較複雜,太多屬性,而且客戶的組合需求多樣化,所以OkHttp使用建造者模式(Build模式:使用多個簡單的對象一步一步構建成一個複雜的對象,一個Builder會一步一步構造最終的對象)
  • 4 工廠方法模式:Call接口提供了內部接口Factory(用於將對象的創建延遲到該工廠類的子類中進行),從而實現動態的配置。(工廠方法模式:這種類型屬於創建型模式,它提供了一種創建對象的最佳方式。在工廠模式中,我們創建對象時不會對客戶端暴露創建邏輯,並且使通過使用一個共同的接口來指向新創建的對象。)
  • 5 享元模式:在Dispatcher的線程池中,用到了享元模式,一個不限容量的線程池,線程空閒時存活時間爲60秒。線程池實現了對象複用,降低線程創建開銷,從設計模式上來講,使用了享元模式(享元模式:嘗試重用現有的同類對象,如果未找到匹配對象,則創建新對象,主要用於減少創建對象的數量,以減少內存佔用和提高性能)
  • 6責任鏈模式:很明顯,在Okhttp中攔截器模塊,執行過程用到。OkHttp3的攔截器鏈中,內置了5個默認的攔截器,分別用於重試、請求對象轉換、緩存、鏈接、網絡讀寫(責任鏈模式:爲請求創建了一個接收者對象的鏈。這種模式給予請求的類型,對請求的發送者和接受者進行解耦。這種類型的設計模式屬於行爲型模式。在這種模式中,通常每個接收者都包含對另一個接受者的引用。如果一個對象不能處理該請求,那麼它會把相同的請求傳給下一個接受者,依此類推)
  • 7策略模式: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.Build()…Build()

  • 第一種:new OkHttpClient(),OkHttp做了很多工作,很多我們需要的參數在這裏獲得默認值,者就是默認設定。
  • 第二種:默認的設置和第一種相同,但是我們可以利用建造者模式單獨的設置每一個屬性;注意事項:OKHttpClient強烈建議全局單例使用,因爲每一個OkHttpClient都有自己單獨的連接池和線程池,複用連接池和線程池能減少延遲、節省內存

2、RealCall類:集成Call類,從源代碼中,可以看到使用Call類,發送出(同步/異步)請求,RealCall的主要作用:發送請求,當中還有攔截器和建立過程,異步回調。

#### 3、Dispatcher類(調度器、多線程):保存同步和異步Call的地方,並負責執行異步AsyncCall

4、攔截器鏈:有供用戶自定義的Interceptor、RetryAndFollowUpInterceptor、BridgeInterceptor、CacheInterceptor、ConnectIntercepyor、NetworkInterceptors、CallServerInterceptor,依次通過以上攔截器,傳遞給RealCall中的ApplicationInterceptorChain。攔截器之所以可以依次調用,並最終再在從後往前返回Response,都依賴於ApplicationCationInterceptorChain的proceed方法、BridgeInterceptor的主要作用就是爲請求(request before)添加請求頭,一個攔截器的intercept方法所執行的邏輯分爲三部分:

  • 在發起請求前對request進行處理
  • 調用下一個攔截器,獲取response
  • 對response進行處理,返回給上一個攔截器

5 HttpEngine類:

核心攔截器

緩存策略:提到緩存策略,就要提到CacheInterceptor攔截器

image

CacheStrategy實現緩存策略,CacheStrategy使用Fatory模式進行構造,該類決定是使用緩存還是使用網絡請求
Cache封裝了實際的緩存操作
DiskLruCache:Cache基於DiskLruCache

RetryAndFollowUpInterceptor

RetryAndFollowUpInterceptor邏輯分爲兩部分
  • 1 在網絡請求失敗後進行重試,
  • 2 當服務器返回當前請求需要進行重定向時直接發起新的請求,並在條件允許的情況下複用當前連接
BridgeInterceptor主要負責添加請求頭
  • 1 設置內容長度,內容編碼
  • 2 設置gzip壓縮,並在接收到內容後進行解壓,省去了應用層數據解壓的麻煩
  • 3 添加cookie
  • 4 設置其他報頭,如User-Agent、Host,Heep-Alive
CacheInterceptor的職責很明確,就是負責Cache的管理
  • 1 當網絡請求符合要求的Cache時直接返回Cache
  • 2 當服務器返回內容有改變時更新當前cache
  • 3 如果當前Cache失效,刪除
  • 4 在CacheInterceptor內部使用了策略模式
ConnectInterceptor的intercept只有一行關鍵代碼
  • 1 即爲當前的請求找到合適的連接,可能複用已經有鏈接也可能重新創建連接,返回的連接由連接池決定

CallServerInterceptor

  • 1 負責向服務器發起真正的訪問請求,並在接收到服務器後讀取響應返回
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章