okhttp分析

okhttp用法
1、創建一個 OkhttpClient對象,使用了外觀模式可以直接new 也可以Builder模式來創建OkhttpClient對象,在builder模式中可以添加攔截器和cookieJar等信息。
2、創建一個Request的請求對象,通過builder方法進行創建,然後添加請求相關的參數如請求方式,請求鏈接,請求頭等信息。
3、通過okhttpClient對象調用newCall方法,並將request對象作爲參數傳入,返回一個call對象。
4、通過這個call對象調用excute方法或是enqueue方法。返回response對象。具體如下代碼

   OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(null)
                .cookieJar(null)
                .build();
                
        Request request = new Request.Builder()
                .url("")
                .get()
                .addHeader("","")
                .build();

        Call call = okHttpClient.newCall(request);

        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {

            }
        });

okhttp執行流程

1、okhttpClient的newCall裏面創建一個RealCall對象並請返回。
2、RealCall對象包含兩個很重要的方法execute和equeue方法。
3、RealCall還有一個很重要的方法getResponseWithInterceptorChine方法新建攔截器鏈,把工作分解成可配置的分段流程。

先說一下execute的執行流程。
1、先會判斷調用的請求是否執行過。如過執行過直接拋異常。
2、然後將當前的call對象存入dispatcher同步隊列當中。
3、執行getResponseWithInterceptorChine()方法返回結果(這時得到來Response對象)。
4、將當前RealCall對象從dispatcher同步隊列中移除。

enqueue執行的流程也是相似的。
1、首先會判斷請求是否執行過,如果執行過直接拋異常。
2、會創建一個AsyncCall對象,添加到dispatcher異步執行隊列當中去,如果正在執行的請求說小於64個,且請求同一主機小於5個則添加到執行隊列當中,創建線程池來執行這個線程。否則進入異步等待隊列。
3、AsyncCall中的execute方法中調用getResponseWithInterceptorChine()得到Response對象。
4、將正在執行的異步隊列從dispatcher中移除,之後會檢測等待隊列,將滿足條件的任務添加到執行隊列中。

getResponseWithInterceptorChine方法
會將我們所有的攔截器組成一個鏈式結構首先是自己定義的攔截器,之後是Okhttp自定義的攔截器,如重試、橋接、緩存、鏈接、網絡等,每一個攔截器都可以處理請求然後直接返回請求。

ApplicationInterceptor 自定義攔截器

BridgeInterceptor:主要對Request中的head設置默認值,比如Conntent-type、Connection、Cookie等。

CacheInterceptor:負責HTTP請求緩存處理。

ConnectInterceptor : 負責建立與服務器地址之間的連接,也就是TCP連接。

NetWorkInterceptor:自定義網絡攔截器。

CallServerInterceptor:負責向服務器發送數據和從服務器裏面獲取數據。

對於在攔截器上添加header和建立TCP連接都是標準流程,可干預的空間不大,主要介紹CahceInterceptor。
NetWorkInterceptor 和ApplicationInterceptor 都是自定義攔截器,就是調用的層級不一樣。NetWorkInterceptor 之前就已經處理了本地相關的攔截器,所以不一定會走到這個攔截器。而ApplicatinInterceptor在本地攔截之前就已經走了。

**說一下常用的攔截器CahceInterceptor
爲什麼要用到緩存。
1、減少服務端的壓力。
2、讀取本地數據更快。
3、在無網的情況下仍然有數據展現。

對於客戶端來講分爲兩種緩存:
1、強制緩存。
首先從緩存數據庫裏面找緩存,看緩存是否失效,如果沒有失效直接返回緩存數據,如果失效則從服務器端獲取新數據和緩存規則,對數據和緩存規則存入緩存數據庫中。
2、對比緩存。
首先從緩存數據庫裏面拿到緩存數據的標識,請求服務器判斷緩存標識數據是否有效,服務器返回未失效,如果有效直接從緩存裏面讀取數據,如果無效則返回數據和緩存規則,將數據和緩存規則存入緩存系統。
知道了緩存的概念,那何時使用強制緩存,何時使用對比緩存,如何確定強制緩存是否失效呢?
答案就是在請求頭中。
強制緩存標誌就是cache-control,可以設置強制緩存的時間(HTTP1.0用到expires ,在HTTP1.1 修改成cache-control)。
對比緩存
對比緩存有兩套規則Last-modified/if-match-sence。和Etag/If-None-Match(優先級更高一些)
第一次請求數據的時候,服務器在響應頭中返回一個Last-motified字段,告訴客戶端最後一次修改的時間。客戶端將數據和Last-motified 等信息存入緩存數據庫中。
第二次請求時,從緩存裏取出Last-motified的值,放入if-modified-sence字段中,作爲請求頭髮到服務器,服務器進行判斷如果文件修改的時間小於活等於if-modified-sence裏面的值則說明緩存有效返回304直接從緩存裏面獲取數據。否則緩存無效直接返回新的數據和緩存規則個客戶端,客戶端在將新的數據和緩存規則存入緩存數據庫中。
這就是HTTP的緩存策略,OKHTTP則是對這種思想的實現。
OKHTTP通過CacheStrategy和CacheIntercept結合實現了上面的所說的功能,在CacheStrategy裏面通過請求頭以及自身的緩存信息來確定緩存是否可用。在CacheIntercept裏面返回,如果緩存可用則直接返回緩存,如果不可用則直接請求服務器看返回的響應頭是否是304,如果是則直接用緩存裏面數據,並更新緩存。如果不是304直接用網絡數據,並判斷是否有緩存文件以及是否可以緩存對數據進行緩存。
還有一個問題就是緩存如何存的問題,以及緩存數據滿了之後如何清除的問題。
在OKHTTP中採用了DiskLruCache算法對緩存數據進行增刪改查。

okhttp的底層實現
底層是socket連接來進行數據傳輸的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章