
image
簡單的回顧下同步/異步
- 同步請求就是執(zhí)行請求的操作是阻塞式,直到 Http 響應(yīng)返回
- 異步請求就類似非阻塞式的請求,它的執(zhí)行結(jié)果一般都是通過接口回調(diào)的方式告知調(diào)用者
什么是攔截器呢?官網(wǎng)給了一個說明:
- 攔截器是OkHttp中提供的一種強大機制,它可以實現(xiàn) 網(wǎng)絡(luò)監(jiān)聽,請求以及響應(yīng)重寫,請求失敗重試 等功。
這里需要注意它這攔截器是不區(qū)分同步還是異步的,不管是同步/異步請求都會用到攔截器的功能來進行網(wǎng)絡(luò)響應(yīng)的獲取。
OkHttp 框架內(nèi)部給我們提供了那些攔截器呢?
- RetryAndFollowUpInterceptor 重試和失敗重定向攔截器(主要是初始化的一些工作,創(chuàng)建StreamAllocation對象,用來傳遞給后面的攔截器)
- BridgeInterceptor 橋接和適配攔截器(主要是補充用戶創(chuàng)建請求當中缺少的一些必要的請求頭)
- CacheInterceptor 緩存攔截器(主要處理緩存功能)
- ConnectInterceptor 連接攔截器(主要負責建立可用的鏈接)——OkHttp核心攔截器,網(wǎng)絡(luò)交互的關(guān)鍵
- CallServerInterceptor 網(wǎng)絡(luò)服務(wù)攔截器(主要負責將請求寫入到 IO 流當中,并且從 IO 流當中獲取服務(wù)端返回給客服端的響應(yīng)數(shù)據(jù))——OkHttp核心攔截器,網(wǎng)絡(luò)交互的關(guān)鍵
那攔截器鏈又是什么呢?
- 當發(fā)送一個請求的時候,實質(zhì)OkHttp會通過一個攔截器的鏈來執(zhí)行OkHttp的請求。
- 這就是所謂的攔截器鏈,執(zhí)行 RetryAndFollowUpInterceptor => 執(zhí)行 BridgeInterceptor => 執(zhí)行 CacheInterceptor => 執(zhí)行 ConnectInterceptor => 執(zhí)行 CallServerInterceptor => 響應(yīng)到
ConnectInterceptor => 響應(yīng)到 CacheInterceptor => 響應(yīng)到 BridgeInterceptor => 響應(yīng)到 RetryAndFollowUpInterceptor
我們可以到源碼中查看

image.png

image.png
我們可以知道不管同步/異步請求都調(diào)用了同一個方法,我們接著去這個 getResponseWithInterceptorChain() 方法看看里面做了什么。

image.png
其實 getResponseWithInterceptorChain() 方法所做的就是構(gòu)成了一個攔截的鏈,然后通過依次執(zhí)行每一個不同功能的攔截器來獲取服務(wù)器的響應(yīng)返回。我們再來看看這方法 他是怎么構(gòu)成的鏈?

image.png
總結(jié)
1創(chuàng)建了一系列的攔截器,并將其放入到一個攔截器的List集合中
2 創(chuàng)建一個攔截器鏈 ReallnterceptorChain,并執(zhí)行攔截器鏈的 proceed() 方法執(zhí)行請求。
我們知道了攔截器的鏈的創(chuàng)建后還得調(diào)用攔截器鏈的 proceed() 方法來執(zhí)行請求。我們又得到 proceed() 方法中去查看。

image.png
由于 Interceptor 是個接口,得到它的實現(xiàn)類 RealInterceptorChain 去查看

image.png
我們直接去看它的一個核心幾處代碼

image.png

image.png
我們具體到一個攔截器RetryAndFollowUpInterceptor中看看加深下理解

image.png
就直接到RetryAndFollowUpInterceptor的intercept方法中去查看。

image.png
總結(jié)
1 發(fā)起請求前對 request 進行處理(頭部,響應(yīng),網(wǎng)絡(luò)等等)
2 調(diào)用下一個攔截器,獲取 response (為什么要調(diào)用下一個攔截器呢?——因為是有攔截器鏈的概念,只有調(diào)用下一個攔截器,才能構(gòu)成這么一個鏈條)
3 對 response 進行處理,并返回給上一個攔截器
這就是 OkHttp 攔截器的一個核心邏輯了。