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()方法
這個方法 構造一個攔截器鏈,經過不同的攔截器,最後返回數據。(後面會介紹)
異步請求
- 前三步驟和同步請求類似,不同的是第四個步驟也就是下方的代碼邏輯,主要是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()異步方法。