OkHttp使用
同步方式
OkHttpClient client = new OkHttpClient.Builder().readTimeout(5, TimeUnit.SECONDS).build();
Request request = new Request.Builder().url("http://www.baidu.com")
.get().build();
Call call = client.newCall(request);
try {
Response response = call.execute();
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
异步方式
OkHttpClient client = new OkHttpClient.Builder().readTimeout(5, TimeUnit.SECONDS).build();
Request request = new Request.Builder().url("http://www.baidu.com")
.get().build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
System.out.println("Fail");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
System.out.println(response.body().string());
}
});
拦截器
OkHttp请求过程解析
Dispatcher类
内部有一个线程池和三个队列,分别是readyAsyncCalls、runningAsyncCalls和runningSyncCalls队列
- runningSyncCalls用于存储同步请求RealCall对象;
- runningAsyncCalls队列用于存储进入队列的异步请求AsyncCall对象;
- readyAsyncCalls队列用于当runningAsyncCalls的尺寸达到maxRequests参数时(默认64)存储新加的异步请求。
同步请求的执行流程
- excute()方法中,先判断是否执行过,如果执行过抛出异常并excuted=true;
- 接下来调用OkHttpClient的dispatcher()方法获得Dispatcher对象并调用其executed(RealCall)方法;
- 然后通过getResponseWithInterceptorChain()方法同步获取响应;
- 最后调用Dispatcher的finished()方法。
Dispatcher在excuted()的时候只是将同步请求加入到了runningSyncCalls队列。
finished()方法做的是从队列中移除请求,并获得还在运行的请求数量。如果没有在运行的请求,执行idleCallback的run()方法。
异步请求的执行流程
- enqueue()方法同样先将executed参数设为true
然后调用Dispatcher的enqueue(AsyncCall)方法,传入了一个AsyncCall对象。
- AsyncCall继承NamedRunnable,实现了execute()方法(这个方法Runnable的run中被调用):
- 首先调用getResponseWithInterceptorChain()方法获取响应,成功后回调onReponse(),失败回调的onFailure();
- 最后,调用Dispatcher的finished()。
- AsyncCall继承NamedRunnable,实现了execute()方法(这个方法Runnable的run中被调用):
那么在enqueue(AsyncCall)方法中:
首先如果正在运行的异步请求的数量符合放入runningAsyncCalls队列的要求,那么放入队列,然后将AsyncCall交给线程池;否则,放入readyAsyncCalls队列;
当线程池执行AsyncCall任务时,它的execute()方法会被调用,getResponseWithInterceptorChain()会去获取响应,最后调用Dispatcher的finished()方法 。
finished()方法中与同步请求不同的是,会调用promoteCalls(),遍历等待队列将请求移动到异步运行队列中。
Volley和OkHttp对比
都支持http请求,get、post方法。
Volley
- 适合进行数据量不大,但通信频繁的网络操作。
- 不适合大文件下载。
- 可直接在主线程调用服务端并处理返回结果。
OkHttp
- 支持https。
- callback回来是在线程里面, 不能刷新UI,需要我们手动处理
- 封装比较麻烦。