Retrofit有一个叫“Call”的抽象类,之所以会有“Call”这个名称,完全是从OKHttp借鉴过来的。因为OKHttp也有一个叫“Call”的抽象类。它们的内容是完全一样的。
OKHttp 中的"Call", 其作用是,完成对OKHttp Request的执行, 可以是异步,也可以是同步。其实现类是RealCall.java,也就是说Request的真正执行是在RealCall里面。
Retrofit 中的"Call", 其作用是, 丰富异步的执行方式。当然开发者依旧可以像使用OKHttp的Call一样使用Retrofit 中的"Call"。
Retrofit中有一个OKHttpCall类,它是Retrofit 中的"Call"的实现类。其作用是,
- 完成对OKHttp 中的"Call"的封装,以及对OKHttp Request的填充, 包括所需要的http header, http body, http method等等。
- 调用RealCall.java,以同步或异步的方式完成request的发送以及response的解析与反馈。
Retrofit中还有一个很重的类CallAdapter,完成对Call的转换,最后利用OKHttpCall的异步方法RealCall.enqueue(), 丰富各种异步实现的方式, 比如,RxJava,CompletableFuture 等。
在Call代码中,
1 . 通过Request request()方法获取到封装好的OKHtttp Request。
2. 同步执行Request的方法, Response<T> execute() 。异步执行Request的方法, void enqueue(Callback<T> callback);
3. 剩下的只是些辅助类。
public interface Call<T> extends Cloneable {
Response<T> execute() throws IOException;
void enqueue(Callback<T> callback);
boolean isExecuted();
boolean isCanceled();
Request request();
Timeout timeout();
}
下面讲解一下,利用类似OKHttp Call的方式使用Retrofit 中的"Call"。
public interface IFileTransferService {
@POST("file/v1/initupload")
Call<ResponseInfo<Object>> initUpload(@HeaderMap Map<String, String> heads, @Body UploadFileInfo uploadFileInfo);
}
IFileTransferService service = mRetrofit.create(IFileTransferService.class);
Call<ResponseInfo<Device>> response = service.initUpload(DefaultHeader, uploadFileInfo);
上面interface代码上, initUpload()方法返回的是Call<ResponseInfo<Object>>, 这个Call是Retrofit的Call。service.initUpload()也一样是Retrofit的Call。
这么做的好处是,开发者可以像使用OKHttp一样使用。
在Retrofit中,最后执行的是OKHttpCall。在OKHttpCall中执行OKHttp的RealCall。
final class OkHttpCall<T> implements Call<T> {
private final RequestFactory requestFactory;
private final Object[] args;
private final okhttp3.Call.Factory callFactory;
private final Converter<ResponseBody, T> responseConverter;
@GuardedBy("this")
private @Nullable okhttp3.Call rawCall;
@Override
public synchronized Request request() {
return getRawCall().request();
}
private okhttp3.Call getRawCall() throws IOException {
okhttp3.Call call = rawCall;
if (call != null) return call;
return rawCall = createRawCall();
}
@Override
public void enqueue(final Callback<T> callback) {
Objects.requireNonNull(callback, "callback == null");
okhttp3.Call call = awCall = createRawCall();
call.enqueue(
new okhttp3.Callback() {
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response;
response = parseResponse(rawResponse);
callback.onResponse(OkHttpCall.this, response);
}
@Override
public void onFailure(okhttp3.Call call, IOException e) {
}
});
}
@Override
public Response<T> execute() throws IOException {
okhttp3.Call call;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
call = getRawCall();
}
return parseResponse(call.execute());
}
private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
return call;
}
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();
rawResponse =
rawResponse
.newBuilder()
.body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
.build();
ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
try {
T body = responseConverter.convert(catchingBody);
return Response.success(body, rawResponse);
}
}
- 在OkHttpCall中有一个 rawCall。 它其实就是OKHttp的RealCall。
- RealCall的获取是通过callFactory获取的。就是OKHttp的OkHttpClient。在Retrofit类的构造器模式里可以找到。
public Retrofit build() {
...
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
...
}
- 在 createRawCall()方法中,Request是靠requestFactory.create(args)生成的。requestFactory就是把注解表示的参数封装成Request。
- execute() 同步执行request请求。
- enqueue()则是异步执行请求。
- parseResponse()解析OKHttp的Response,很重要的一点就是把OKHttp Response的body序列化成对象。T body = responseConverter.convert(catchingBody);
- parseResponse()中还把OKHttp的Response封装成Retrofit的Response, Response.success(body, rawResponse); 额外的作用就是承载T body。
至于RealCall, 是OKHttp的内容,这里不做讲解。