再来看之前的过程:
//步骤1:创建OkHttpClient对象
OkHttpClient client = new OkHttpClient.Builder()
.readTimeout(5, TimeUnit.SECONDS)
.build();
//步骤2:创建Request对象
Request request = new Request.Builder()
.url("http://www.baidu.com")
.get()
.build();
//步骤3:创建Call对象
Call call = client.newCall(request);
//步骤4:进行请求
//异步请求方式
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());
}
});
//同步请求方式
Response response = call.execute();
已经完成了OkHttpClient和Request对象的创建过程,接下来看一下Call对象的创建过程。
Call源码
call是一个接口,面向接口编程呐!
public interface Call extends Cloneable {
/** Returns the original request that initiated this call. */
//返回原始的请求对象,就是我们上面创建的Request啦
Request request();
/**
* Invokes the request immediately, and blocks until the response can be processed or is in
* error.
*同步请求调用的方法。立刻执行请求,并阻塞至回复返回,或者请求发生错误
*/
Response execute() throws IOException;
/**
* Schedules the request to be executed at some point in the future.
* 异步请求调用的方法。将请求入队列。
* 请求结果返回时会回调用户实现的Callback
*/
void enqueue(Callback responseCallback);
/** Cancels the request, if possible. Requests that are already complete cannot be canceled. */
//如果可以,取消这个请求。已经执行完成的请求无法被取消
void cancel();
/**
* Returns true if this call has been either {@linkplain #execute() executed} or {@linkplain
* #enqueue(Callback) enqueued}. It is an error to execute a call more than once.
*/
//当前这个Call是否已经被执行。一个Call不能执行多次,只能执行一次。
boolean isExecuted();
//当前这个Call是否已经被取消
boolean isCanceled();
/**
* Create a new, identical call to this one which can be enqueued or executed even if this call
* has already been.
*/
//创建一个新的,完全一样的Call,即使,这个Call已经被加入队列,或者已经被执行过了
Call clone();
//内部接口,主要是提供Call的工厂
interface Factory {
//创建新的Call,里面包含了Request对象。
Call newCall(Request request);
}
}
可以看到Call接口提供的功能有:
-
返回当前Call对响应的Request对象;
-
同步请求方法;
-
异步请求方法;
-
取消这个请求的方法;
-
判断这个请求是否已经执行;
-
判断这个请求是否已经取消;
-
克隆一个Call对象;
-
提供内部创建Call对象的工厂的接口;
Request对象就是要去的目的地,Call就是通往目的地的整个过程的的抽象。
Call创建
//步骤3:创建Call对象
Call call = client.newCall(request);
通过OkHttpClient的对象调用newCall方法来完成了。其实OkHttpClient实现了Call.Factory:
public class OkHttpClient implements Cloneable, Call.Factory, WebSocket.Factory {
... ...
/**
* Prepares the {@code request} to be executed at some point in the future.
*/
@Override public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
... ...
}
这里又出现了RealCall这个类,这个类实现了Call接口,通过类名可以看到,它是我们真正需要的Call。
final class RealCall implements Call {
final OkHttpClient client;//我们之前创建的OkHttpClient
final RetryAndFollowUpInterceptor retryAndFollowUpInterceptor;//重试和重定向拦截器
private EventListener eventListener;
/** The application's original request unadulterated by redirects or auth headers. */
//应用原始的请求,未被重定向和为加头部
final Request originalRequest;
final boolean forWebSocket;//是否是webSocket
private boolean executed;//是否被执行过
private RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
this.client = client;
this.originalRequest = originalRequest;
this.forWebSocket = forWebSocket;
//创建重试和重定向的拦截器。仅仅是传入了OkHttpClient对象和forWebSocket值。
this.retryAndFollowUpInterceptor = new RetryAndFollowUpInterceptor(client, forWebSocket);
}
//外部调用这个方法
static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
// Safely publish the Call instance to the EventListener.
RealCall call = new RealCall(client, originalRequest, forWebSocket);
call.eventListener = client.eventListenerFactory().create(call);//创建了一个请求过程的监听
return call;//返回我们创建的RealCall。
}
}
在创建RealCall的过程中做了以下事情:
-
持有OkHttpClient对象;
-
持有Request;
-
持有重定向拦截器RetryAndFollowUpInterceptor;
-
持有事件监听器EventListener;
就相当于,在旅行过程这个对象中,我们持有了汽车,目的地,地图(重试重定向),事件处理能力/监听;
这样,我们完成了RealCall的创建过程。