OkHttp 異步請求

image
image
在上兩篇文章中介紹了OkHttp同步請求以及同步請求的源碼分析,其中也提到了OkHttp的同步請求和異步請求的前三步是一模一樣的流程。

這前三步是:

  • 第一步 創(chuàng)建 OkHttpClient 對象(OkHttpClient代表是客服端類)
  • 第二步 同樣以Builder的模式創(chuàng)建了 Request 對象
  • 第二步 創(chuàng)建 Call 對象(將創(chuàng)建的request封裝成了Call對象)
如果不清楚明細可以查看上兩篇文章OkHttp同步請求OkHttp同步請求 源碼分析的前三步分析。

前三步在前面的文章已分析過了,那直接看異步請求的第四步:

通過 call 對象調(diào)用enqueue(Callback responseCallback)方法發(fā)送異步請求

這也是OkHttp同步異步請求的分水嶺,我們直接看以下代碼:

        //第一步 創(chuàng)建OkHttpClient對象
        OkHttpClient client = new OkHttpClient.Builder().build();
        //第二步 創(chuàng)建Request對象
        Request request = new Request.Builder().url("https://gank.io/api/xiandu/categories").build();
        //第三步 創(chuàng)建Call對象(Call其實是一個接口,具體實現(xiàn)還是RealCall類中)
        Call call = client.newCall(request);
        //第四步 call對象調(diào)用enqueue()方法,通過Callback()回調(diào)拿到響應(yīng)體Response
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                //異步請求失敗之后的回調(diào)
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                //異步請求成功之后的回調(diào)
                
            }
        });

在上面的代碼我們知道了OkHttp異步請求是 call 對象調(diào)用的 enqueue() 方法

這里需要注意的是當調(diào)用的 enqueue() 方法的時候,它是回去開啟一個新的工作線程,然后OkHttp會讓這個網(wǎng)絡(luò)請求在這個工作線程中去執(zhí)行,也就是子線程中去執(zhí)行。

然后通過 Callback()回調(diào)了請求的結(jié)果。

  • onResponse(Call call, Response response)方法是請求成功的回調(diào),可以在里面進行成功的數(shù)據(jù)處理
  • onFailure(Call call, IOException e) 方法是請求失敗的回調(diào),可以在里面進行失敗的數(shù)據(jù)處理

接下來我們通過以上代碼異步請求數(shù)來展示出來

call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                //異步請求失敗之后的回調(diào)
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                //異步請求成功之后的回調(diào)
                txtView.setText(response.body().string ());
            }
        });

我們運行看結(jié)果:


image.png

app 出錯了...? 什么原因呢?我們看下錯誤信息


image.png

image.png

錯誤說:只有UI線程才能去更新控件

 txtView.setText(response.body().string ());

也就說明我們這段顯示響應(yīng)信息的代碼是在子線程中執(zhí)行的。從而反應(yīng)出我們的 new Callback() 回調(diào)方法并不是在我們的主線程里,而是在子線程里。

那我們改造下代碼,將顯示響應(yīng)信息放在主線程中再去執(zhí)行。

        //第四步 call對象調(diào)用enqueue()方法,通過Callback()回調(diào)拿到響應(yīng)體Response
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                //異步請求失敗之后的回調(diào)
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                //異步請求成功之后的回調(diào)
                final String str = response.body().string ();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        txtView.setText(str);
                    }
                });

            }
        });

這樣就沒有問題了!

注意事項:onResponse() 和 onFailure() 兩個回調(diào)方法都是在工作線程也就是子線程當中去執(zhí)行的

這里異步請求就完成了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容