在上两篇文章中介绍了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 ());
}
});
我们运行看结果:
app 出错了...? 什么原因呢?我们看下错误信息
错误说:只有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() 两个回调方法都是在工作线程也就是子线程当中去执行的
这里异步请求就完成了。