image
在上兩篇文章中介紹了OkHttp同步請(qǐng)求以及同步請(qǐng)求的源碼分析,其中也提到了OkHttp的同步請(qǐng)求和異步請(qǐng)求的前三步是一模一樣的流程黎侈。
這前三步是:
- 第一步 創(chuàng)建 OkHttpClient 對(duì)象(OkHttpClient代表是客服端類)
- 第二步 同樣以Builder的模式創(chuàng)建了 Request 對(duì)象
- 第二步 創(chuàng)建 Call 對(duì)象(將創(chuàng)建的request封裝成了Call對(duì)象)
如果不清楚明細(xì)可以查看上兩篇文章OkHttp同步請(qǐng)求和OkHttp同步請(qǐng)求 源碼分析的前三步分析相嵌。
前三步在前面的文章已分析過了魔种,那直接看異步請(qǐng)求的第四步:
通過 call 對(duì)象調(diào)用enqueue(Callback responseCallback)方法發(fā)送異步請(qǐng)求
這也是OkHttp同步異步請(qǐng)求的分水嶺悠栓,我們直接看以下代碼:
//第一步 創(chuàng)建OkHttpClient對(duì)象
OkHttpClient client = new OkHttpClient.Builder().build();
//第二步 創(chuàng)建Request對(duì)象
Request request = new Request.Builder().url("https://gank.io/api/xiandu/categories").build();
//第三步 創(chuàng)建Call對(duì)象(Call其實(shí)是一個(gè)接口色解,具體實(shí)現(xiàn)還是RealCall類中)
Call call = client.newCall(request);
//第四步 call對(duì)象調(diào)用enqueue()方法痘昌,通過Callback()回調(diào)拿到響應(yīng)體Response
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//異步請(qǐng)求失敗之后的回調(diào)
}
@Override
public void onResponse(Call call, Response response) throws IOException {
//異步請(qǐng)求成功之后的回調(diào)
}
});
在上面的代碼我們知道了OkHttp異步請(qǐng)求是 call 對(duì)象調(diào)用的 enqueue() 方法
這里需要注意的是當(dāng)調(diào)用的 enqueue() 方法的時(shí)候钥勋,它是回去開啟一個(gè)新的工作線程,然后OkHttp會(huì)讓這個(gè)網(wǎng)絡(luò)請(qǐng)求在這個(gè)工作線程中去執(zhí)行控汉,也就是子線程中去執(zhí)行笔诵。
然后通過 Callback()回調(diào)了請(qǐng)求的結(jié)果。
- onResponse(Call call, Response response)方法是請(qǐng)求成功的回調(diào)姑子,可以在里面進(jìn)行成功的數(shù)據(jù)處理
- onFailure(Call call, IOException e) 方法是請(qǐng)求失敗的回調(diào)乎婿,可以在里面進(jìn)行失敗的數(shù)據(jù)處理
接下來我們通過以上代碼異步請(qǐng)求數(shù)來展示出來
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//異步請(qǐng)求失敗之后的回調(diào)
}
@Override
public void onResponse(Call call, Response response) throws IOException {
//異步請(qǐng)求成功之后的回調(diào)
txtView.setText(response.body().string ());
}
});
我們運(yùn)行看結(jié)果:
image.png
app 出錯(cuò)了...? 什么原因呢?我們看下錯(cuò)誤信息
image.png
image.png
錯(cuò)誤說:只有UI線程才能去更新控件
txtView.setText(response.body().string ());
也就說明我們這段顯示響應(yīng)信息的代碼是在子線程中執(zhí)行的街佑。從而反應(yīng)出我們的 new Callback() 回調(diào)方法并不是在我們的主線程里谢翎,而是在子線程里。
那我們改造下代碼沐旨,將顯示響應(yīng)信息放在主線程中再去執(zhí)行森逮。
//第四步 call對(duì)象調(diào)用enqueue()方法,通過Callback()回調(diào)拿到響應(yīng)體Response
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//異步請(qǐng)求失敗之后的回調(diào)
}
@Override
public void onResponse(Call call, Response response) throws IOException {
//異步請(qǐng)求成功之后的回調(diào)
final String str = response.body().string ();
runOnUiThread(new Runnable() {
@Override
public void run() {
txtView.setText(str);
}
});
}
});
這樣就沒有問題了磁携!
注意事項(xiàng):onResponse() 和 onFailure() 兩個(gè)回調(diào)方法都是在工作線程也就是子線程當(dāng)中去執(zhí)行的
這里異步請(qǐng)求就完成了褒侧。