OkHttp 异步请求

image
在上两篇文章中介绍了OkHttp同步请求以及同步请求的源码分析,其中也提到了OkHttp的同步请求和异步请求的前三步是一模一样的流程。

这前三步是:

  • 第一步 创建 OkHttpClient 对象(OkHttpClient代表是客服端类)
  • 第二步 同样以Builder的模式创建了 Request 对象
  • 第二步 创建 Call 对象(将创建的request封装成了Call对象)
如果不清楚明细可以查看上两篇文章OkHttp同步请求和OkHttp同步请求 源码分析的前三步分析。

前三步在前面的文章已分析过了,那直接看异步请求的第四步:

通过 call 对象调用enqueue(Callback responseCallback)方法发送异步请求

这也是OkHttp同步异步请求的分水岭,我们直接看以下代码:

        //第一步 创建OkHttpClient对象
        OkHttpClient client = new OkHttpClient.Builder().build();
        //第二步 创建Request对象
        Request request = new Request.Builder().url("https://gank.io/api/xiandu/categories").build();
        //第三步 创建Call对象(Call其实是一个接口,具体实现还是RealCall类中)
        Call call = client.newCall(request);
        //第四步 call对象调用enqueue()方法,通过Callback()回调拿到响应体Response
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                //异步请求失败之后的回调
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                //异步请求成功之后的回调
                
            }
        });

在上面的代码我们知道了OkHttp异步请求是 call 对象调用的 enqueue() 方法

这里需要注意的是当调用的 enqueue() 方法的时候,它是回去开启一个新的工作线程,然后OkHttp会让这个网络请求在这个工作线程中去执行,也就是子线程中去执行。

然后通过 Callback()回调了请求的结果。

  • onResponse(Call call, Response response)方法是请求成功的回调,可以在里面进行成功的数据处理
  • onFailure(Call call, IOException e) 方法是请求失败的回调,可以在里面进行失败的数据处理

接下来我们通过以上代码异步请求数来展示出来

call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                //异步请求失败之后的回调
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                //异步请求成功之后的回调
                txtView.setText(response.body().string ());
            }
        });

我们运行看结果:


image.png

app 出错了...? 什么原因呢?我们看下错误信息


image.png

image.png

错误说:只有UI线程才能去更新控件

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

也就说明我们这段显示响应信息的代码是在子线程中执行的。从而反应出我们的 new Callback() 回调方法并不是在我们的主线程里,而是在子线程里。

那我们改造下代码,将显示响应信息放在主线程中再去执行。

        //第四步 call对象调用enqueue()方法,通过Callback()回调拿到响应体Response
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                //异步请求失败之后的回调
            }

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

            }
        });

这样就没有问题了!

注意事项:onResponse() 和 onFailure() 两个回调方法都是在工作线程也就是子线程当中去执行的

这里异步请求就完成了。

你可能感兴趣的:(OkHttp 异步请求)