OkHttp源碼學習筆記(一)請求流程分析

最近看了OkHttp(3.11.0)的源碼,想總結下本身對OkHttp的認識,加深印象,若有不對的地方歡迎各位大佬指正。安全

一、OkHttp簡單的異步請求。

OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new Request.Builder().url(url).build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {

            @Override
            public void onResponse(Call call, Response response) throws IOException {

            }

            @Override
            public void onFailure(Call call, IOException e) {

            }
        });
複製代碼

OkHttp的請求分四步:bash

  • 1.建立OkHttpClient對象
  • 2.建立Request對象封裝請求url以及請求參數
  • 3.經過OkhttpClient對象和Request對象獲得Call對象
  • 4.最終經過Call對象來執行請求。

二、經過跟蹤Call的enqueue方法探索OkHttp的請求過程

image.png
這裏咱們會發現Call是一個接口,真正實現enqueue方法的是RealCall對象,因此這裏展現的也是RealCall的enqueue方法。前面的同步代碼塊主要是防止enqueue方法屢次執行的,99行主要是將當前Call對象加入到事件監聽裏面。這裏核心的是100行。100行又調用了Dispatcher(Okhttp任務調度類)的equeue方法。而後用Callback對象建立了AsyncCall對象。

三、探索AsyncCall類的真面目

image.png
這裏我發現AsyncCall繼承於NamedRunnable類。
image.png
而NamedRunnable類又是一個實現Runnable接口的抽象類,並在run方法中執行了execute方法。而AysbcCall又繼承了NamedRunnable,因此AysncCall也是一個Runnable,回過頭再看AysncCall的execute方法,不難發現這就是AysncCall類的核心。

四、回過頭咱們看下Dispatcher的enqueue方法

image.png
這是一個同步的,線程安全的方法。runningAsyncCalls是一個正在執行的存儲AysncCall的隊列,readyAsyncCalls是一個等待執行的存儲AysncCall的隊列。maxRequests在Okhttp中定義的正在執行最大請求數是64,支持修改。maxRequestsPerHost在Okhttp中定義的同一主機請求最大數爲5。因此這段的含義是判斷當前正在執行的請求數和與當前同一主機數是否超過了最大限制,若是超過了限制把AysncCall加入到等待執行隊列,不然加入到正在執行隊列,並用線程池執行AysncCall,這時會調用AysncCall的execute方法

五、這時候再看AsyncCall的execute方法

image.png
這裏的147行是okhttp的核心經過一系列的攔截器生成最後的返回Response。以後的148行到162行都是判斷這次請求是否成功經過傳入的CallBack返回請求結果。164行咱們又見到了Dispatcher對象,在這裏調用了他的finished方法,將當前AsyncCall對象傳了進去。這裏咱們進去看下最後調用的finished方法。
image.png
image.png
這裏202行將當前的AysncCall對象從正在執行的請求隊列runningAsyncCalls中移除了。而後咱們主要點進去203行看promoteCalls方法。
image.png
這裏 先是判斷了正在執行的請求數是否大於最大請求數,而且等待執行請求隊列不爲空。而後遍歷等待執行請求隊列,取出其中的AsyncCall對象,判斷當前正在執行隊列中與這個AsyncCall對象相同的主機數有沒有達到最大值。若是沒有的話則把AsyncCall對象從等待執行隊列中移除,加入到正在執行的隊列,並用線程池執行這個AsyncCall對象。

六、總結Okhttp內容進行一次網絡請求流程。

  • 一、ReallCall對象的enqueue方法建立一個內部類AysncCall對象。
  • 二、調用Diapatcher的enqueque方法判斷是否知足執行此AysncCall條件,知足則將其加入到正在執行的請求隊列中,並開始執行,不知足則將其加入到等待執行的請求隊列中。
  • 三、AysncCall的execute方法經過OkHttp一系列的攔截器生成此次請求的Response對象,經過CallBack對象將請求結果傳遞給調用者。
  • 四、調用Diapatcher的finished的方法將此AysncCall對象從正在執行的隊列中移除,遍歷等待執行的隊列,從中取出知足執行條件的AysncCall對象,將其添加到正在執行的隊列中,並執行此AysncCall對象。如此這樣反覆循環。
  • 五、這裏總結的是一次請求是怎麼被分配執行的,而請求生成結果的核心仍是在AysncCall的execute方法中的第147行,經過攔截器鏈生成返回結果。
相關文章
相關標籤/搜索