OkHttp源碼解讀總結(二)--->OkHttp同步/異步請求

OkHttp源碼解讀總結(二)—>OkHttp同步/異步請求

標籤(空格分隔): OkHttp源碼 學習筆記


前言

  • 以下的相關知識總結是通過慕課網的相關學習和自己的相關看法,如果有需要的可以去查看一下慕課網的相關教學,感覺還可以。

OkHttp同步請求

同步請求簡單步驟

  /**
     * 構建OkHttpClient對象
     *
     * @return OkHttpClient
     */
    public OkHttpClient getOkHttpClient() {

        return new OkHttpClient.Builder()
                .connectTimeout(10000, TimeUnit.MILLISECONDS)
                .readTimeout(10000, TimeUnit.MILLISECONDS)
                .writeTimeout(10000, TimeUnit.MICROSECONDS)
                .build();
    }

    /**
     * 同步請求
     */
    public void synRequest() {

        Request request = new Request.Builder().url("http://www.baidu.com")
                .get()
                .build();

        Call requestCall = getOkHttpClient().newCall(request);

        try {
            Response response = requestCall.execute();
            if (response.isSuccessful()) {
                String json = response.body().string();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

1、獲取OkHttpClient

new OkHttpClient.Builder()
                .connectTimeout(10000, TimeUnit.MILLISECONDS)
                .readTimeout(10000, TimeUnit.MILLISECONDS)
                .writeTimeout(10000, TimeUnit.MICROSECONDS)
                .build()

代表着okhttp請求的客戶端類,很多的功能需要這個客戶端類進行轉發或者實現,而他的創建主要有兩種方法:

  • 第一種方法
    • new OkHttpClient()
  • 第二種方法
    • new OkHttpClient.Builder().build()來創建
    • 因爲要考慮要其他請求
      • 網絡複雜(連接超時/讀取超時…)
      • 需要設置其他參數(攔截器/分發器等…)

2、獲取Request請求對象

 Request request = new Request.Builder()
 .url("http://www.baidu.com")  //
                .get()
                .build();

代表着請求的報文信息,比如請求的方法、請求頭、請求地址,這個Request也是通過構建者模式來創建。

3、獲取okhttp3.Call對象

 Call requestCall = getOkHttpClient().newCall(request);

這個Call對象,就相當於實際的OkHttp請求,也就是可以把他理解爲是Request請求和Response響應的一個橋樑,通過client的newCall()方法,傳入我們之前創建好的request對象。要注意,這個之前和同步請求和異步請求沒什麼區別,在接下來的步驟就是實現的同步或者異步請求的邏輯了。也就是前三步驟只是爲了獲取實際的請求Call。

4、Call對象的execute()同步請求方法

  //同步請求
  Response response = requestCall.execute();
  //響應成功
  if (response.isSuccessful()) {
      //通過響應的body().string()方法獲取返回回來的json數據(也可以是其他類型的數據(XML類型)  這個需要和服務器端商量好)
      String json = response.body().string();
  }

通過execute()方法來獲取響應報文的讀取,Response顧名思義就是響應體,其中包含了響應頭,響應實體信息,同步和異步請求最大的區別就是這個第四步驟,因爲異步請求調用的則是enqueue()方法,傳入CallBack進行數據的成功和失敗邏輯

同步請求總結

  • 1、創建OkHttpClient和Requet對象
  • 2、將Request封裝成Call對象
  • 3、調用Call的execute()方法同步請求

同步請求發送之後,就會進入阻塞狀態,直到收到響應。而且也只有同步請求會阻塞,異步請求是新開的線程做網絡請求.

如下圖:不管事同步還是異步請求,最終都會經過getResponseWithInterceptorChain()方法 這個方法 構造一個攔截器鏈,經過不同的攔截器,最後返回數據。(後面會介紹)

image.png

異步請求

  • 前三步驟和同步請求類似,不同的是第四個步驟也就是下方的代碼邏輯,主要是call的enqueue()方法,傳入相應的CallBack進行數據返回之後的返回和錯誤處理。
 requestCall.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                //當請求出錯的時候  會回調到這個方法中
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                //要注意這個地方是子線程,okhttp並沒有給我們把響應的數據轉換到主線程中,因此我們在這個地方更新UI的時候
                //是會報錯的  需要我們手動的轉換到主線程  然後才進行數據的解析和UI更新   在之前的retrofit的講解中
                //也稍微有所涉及  那就是retrofit已經幫我們把異步的這個請求  返回來的callback已經切換到了主線程
                //得益於retrofit裏面的Executorer這個回調執行器
                if (response.isSuccessful()){
                    String string = response.body().string();
                }
            }
        });

因此可以看到,同步請求和異步請求的差異在於第四步,也就是execute()同步方法和enqueue()異步方法。

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