1 使用
首先从一个简单使用例子开始入手,下面的是源码中的一个例子:
OkHttpClient client = new OkHttpClient();//步骤1
// Create request for remote resource.
Request request = new Request.Builder()
.url(ENDPOINT)
.build();//步骤2
// Execute the request and retrieve the response.
try (Response response = client.newCall(request).execute()) {
//步骤3
// Deserialize HTTP response to concrete type.
ResponseBody body = response.body();
List<Contributor> contributors = CONTRIBUTORS_JSON_ADAPTER.fromJson(body.source());
// Sort list by the most contributions.
Collections.sort(contributors, (c1, c2) -> c2.contributions - c1.contributions);
// Output list of contributors.
for (Contributor contributor : contributors) {
System.out.println(contributor.login + ": " + contributor.contributions);
}
}
步骤1: 创建一个OkHttpClient对象。
步骤2:通过建造者模式创建一个请求,这边可以配置Url等数据。
步骤3:加载请求并执行等待响应。
至此一个基本的请求过程编写完成。
2 同步与异步请求
Call对象由client的newCall生成,其中有两种方式。第一种是execute(),它会阻塞当前线程。第二种是enqueue,它并不会阻塞线程,而是将任务交给线程池去处理,处理完再将结果 返回回来。那么接下来看看client.newCall(request)是怎么一回事:
@Override public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
可见它是通过OKHttpClient,Request等创建了一个新的RealCall对象。那么这个实际执行请求回调操作的也就是RealCall对象。先看看它的同步方式:
@Override public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
transmitter.timeoutEnter();
transmitter.callStart();
try {
client.dispatcher().executed(this);
return getResponseWithInterceptorChain();
} finally {
client.dispatcher().finished(this);
}
}
synchronized void executed(RealCall call) {
runningSyncCalls.add(call);
}
流程如下:execute() --> client.dispatcher().executed(this) --> runningSyncCalls.add(call) --> getResponseWithInterceptorChain() --> client.dispatcher().finished(this)
首先是将该call加入runningSyncCalls,这表示该任务已经子啊执行了。然后调用getResponseWithInterceptorChain方法也就是开始请求了。这都是发生在当前线程所以会阻塞线程。最后会调用dispatcher的finish方法,该方法会去通知线程池开始去运行等待任务,这个finish方法方法后面会分析。
@Override public void enqueue (Callback responseCallback) {
。。。
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
void enqueue(AsyncCall call) {
synchronized (this) {
readyAsyncCalls