OkHttp五大攔截器(自己專業整理)
阿新 • • 發佈:2018-12-17
一、什麼是OkHttp3
(1)定義:
OkHttp3是一個處理網路請求的開源專案,是目前最火的網路框架,作者是Square公司,
用於代替Android提供的HttpConnection和HttpClient。**
(2)OkHttp的特點
1、是基於建造者模式(將一個複雜物件的構建與它的表示分離,用於屬性引數很多 時。)建立的
建造者模式:https://www.jianshu.com/p/be290ccea05a
2、鏈式呼叫,每一個方法的返回值型別都是當前類的物件
(3)它的優點是什麼
支援HTTP2/SPDY(SPDY是Google開發的基於TCP的傳輸層協議,用以最小化網路延遲,提升網路速度,優化使用者的網路使用體驗。)
socket自動選擇最好路線,並支援自動重連,擁有自動維護的socket連線池,減少握手次數,減少了請求延遲,
共享Socket,減少對伺服器的請求次數。
擁有Interceptors輕鬆處理請求與響應(自動處理GZip壓縮)。
二、OKHttp的功能
PUT,DELETE,POST,GET等請求
檔案的上傳下載
載入圖片(內部會圖片大小自動壓縮)
支援請求回撥,直接返回物件、物件集合
支援session的保持
OkHttp請求流程
使用 OkHttp 發起一個請求主要三步:
1、需要構造一個 OkHttpClient
2、構造請求資訊 Request
3、發起請求
OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder().url("http://www.baidu.com") .build(); try { Response response = client.newCall(request).execute(); if (response.isSuccessful()) { System.out.println("成功"); } } catch (IOException e) { e.printStackTrace(); }
發起一個請求整體流程:
首先當OkHttpClient物件想要傳送一個網路請求的時會執行newCall()方法這是我們將Request放在這個方法裡邊,
之後通過返回的okhttp的物件去去呼叫newCall方法
我們是從newCall開始的在原始碼中newCall會給我們返回個RealCall,newRealCall();
在RealCall中會將我們傳進來的request傳給我們的OrigginalRequest物件
(OrigginalRequest之後會在getresponseIntecepterchain裡的攔截鏈RealInterceptorChain()呼叫)
接下來如果我們是去進行一個同步請求的話也就是在程式碼當中呼叫excute()方法
進入excute()方法之後首先會先呼叫client。dispatcher()。excute(this);
這個方法的目的是通知調節器dispatcher我現在要開始執行任務瞭然後呼叫了getresponseInterceptorchain()方法
在這個方法執行結束以後會給我們返回一個通過http請求獲取的request物件
最後會呼叫client。dispatcher。finish()來通知排程器dispatcher我現在任務執行結束了你可以讓其他的認為來執行了
然後我們來說說它具體的執行過程,具體的執行過程是·在getresponseInterceptorchain()中執行的
**在這個方法裡有一個泛型是interceptor也就是攔截器的集合在這個結合裡存入了5個攔截器
之後建立了一個攔截鏈RealInt**erceptorChain();通過我們攔截鏈獲取的物件去呼叫process()方法
這個也就是我們所說的鏈式呼叫
在這個方法中有一個索引值index每次我們去呼叫這個process方法的時候他都會加1**
然**後我們會根據這個索引值去判斷我們去呼叫哪個攔截器當我們第一次呼叫這個方法的時候index為1回去呼叫我們集合當中
的第一個攔截器當攔截器執行完畢之後會去建立一個新的攔截鏈並且通過這個新的攔截鏈去再次呼叫process方法
然後去執行下一個攔截器
一直到所有的攔截器都呼叫完畢它會給我們返回一個的Request物件
而這個過程就是一個遞迴;
那麼它是如何去判斷我們已經呼叫到最後一個攔截器了那?
它是通過索引值index當index>集合的長度的時候那麼它就會結束這個方法了因為我們index是從1開始的
所以需要index值大於集合長度的時候
我們集合裡的攔截器才會全部執行完畢
然後我們去說一說這5個攔截器都是什麼分別有什麼作用
(五大攔截器)
一、RetryAndFollowUpInterceptor (重定向攔截器)
RetryAndFollowUpInterceptor 的攔截操作中做了這麼幾件事:
1、建立一個 StreamAllocation
2、發起請求
3、請求異常時會重試
4、根據響應碼做重定向和重試
5、重定向時如果地址不一致會釋放連線
6、另外也儲存是否取消的狀態值,在重試、請求得到響應後都會判斷是否取消
二、BridgeInterceptor (橋接攔截器)
內建的攔截器中第二個是 BridgeInterceptor。Bridge,橋,什麼橋?連線使用者請求資訊 和 HTTP 請求的橋樑。
BridgeInterceptor 負責把使用者構造的請求轉換為傳送到伺服器的請求、把伺服器返回的響應轉換為使用者友好的響應。
我們說下僑界攔截器大概都做了什麼吧,請求前:
1、如果這個請求有請求體,就新增 Content-Type, Content-Length 等
2、如果這個請求沒有 Host,就通過 url 來獲取 Host 值新增到 Header 中
3、如果這個請求沒有接收的資料型別Accept-Encoding,且沒指定接收的資料範圍,就新增預設接受格式為 gzip
5、去 CookieJar 中根據 url 查詢 Cookie 新增到 Header
6、如果當前沒有,就新增 User-Agent 資訊
發起請求後:
7、解析響應 Header 中的 Cookie
8、如果想要資料的格式是 gzip,就建立 GzipSource 進行解壓,同時移除 Content-Encoding 和 Content-Length
三、CacheInterceptor (快取攔截器)
第三個攔截器是快取處理攔截器 CacheInterceptor,它的重要性用一句話來描述:最快的請求就是不請求,直接用快取。
首先,根據request來判斷cache中是否有快取的response,如果有,得到這個response,然後進行判斷當前response是否有效,
沒有將cacheCandate賦值為空。
根據request判斷快取的策略,是否要使用了網路,快取 或兩者都使用
呼叫下一個攔截器,決定從網路上來得到response
如果本地已經存在cacheResponse,那麼讓它和網路得到的networkResponse做比較,決定是否來更新快取的cacheResponse
快取未經快取過的response
、