一、使用OkHttp
OkHttp发送请求后,可以通过同步或异步地方式获取响应。下面就同步和异步两种方式进行介绍。
1.1、同步方式
发送请求后,就会进入阻塞状态,知道收到响应。下面看一个下载百度首页的例子:
-
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和Request对象,两者均使用了Builder模式;然后将Request封装成Call对象,然后调用Call的execute()同步发送请求,最后打印响应。
1.2、异步方式
异步方式是在回调中处理响应的,同样看下载百度首页的例子:
-
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来负责的,负责请求的分发的发起。实际执行请求的是ConnctionPool
同步请求
同一时刻只能有一个任务发起,synchronized关键字锁住了整个代码,那么如果当前OkhttpClient已经执行了一个同步任务,如果这个任务没有释放锁,那么新发起的请求将被阻塞,直到当前任务释放锁
@Override public Response execute() throws IOException { //同一时刻只能有一个任务执行 因为是阻塞式的 由synchronized关键字锁住 synchronized (this) { if (executed) throw new IllegalStateException("Already Executed"); executed = true; } captureCallStackTrace(); try { client.dispatcher().executed(this); Response result = getResponseWithInterceptorChain(); if (result == null) throw new IOException("Canceled"); return result; } finally { client.dispatcher().finished(this); } }
异步请求
同一时刻可以发起多个请求,因为异步请求每一个都是在一个独立的线程,由两个队列管理,并且synchronized只锁住了代码校验是否执行的部分。
@Override public void enqueue(Callback responseCallback) { synchronized (this) { if (executed) throw new IllegalStateException("Already Executed"); executed = true; } //异步请求同一时刻可以有多个任务执行,由两个队列管理 captureCallStackTrace(); client.dispatcher().enqueue(new AsyncCall(responseCallback)); }