在上一篇中介绍来Retrofit如何使用,如果有不清楚Retrofit的使用的话可以看我的上一篇文章Retrofit快速入门使用
那么这一篇我们就从源码的角度来深入的了解Retrofit的实现,本篇文章基于Retrofit2.4.0来分析。
一般我们会使用如下方式来创建一个retrofit对象,
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://www.sojson.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
weatherInterface = retrofit.create(WeatherInterface.class);
Call<Weather> callSZ = weatherInterface.getWeather("深圳");
callSZ.enqueue(new Callback<Weather>() {
@Override
public void onResponse(Call<Weather> call, Response<Weather> response) {
weatherInfo.setText(response.body().toString());
}
@Override
public void onFailure(Call<Weather> call, Throwable t) {
weatherInfo.setText("请求失败");
}
});
那么,就这么几步到底做了那些事情呢,下面我们来一步一步的分析它们。
step1:创建builder
Retrofit使用来构建者模式来创建Retrofit对象,和OkHttp的风格一样。
public Builder() {
//获取一个平台对象
this(Platform.get());
}
在Builder的构造方法中获取了一个和平台相关的Platform对象,Retrofit目前支持Android平台和java平台,不过在之前版本的代码中还会支持IOS平台。进入Platform中查看它的源码,因为代码不多,这里就全部贴出来了。
class Platform {
//Platform在被加载后就会获取当前的平台对象
private static final Platform PLATFORM = findPlatform();
static Platform get() {
return PLATFORM;
}
//findPlatform()是根据不同平台中的类来确定当前的运行环境是什么平台
private static Platform findPlatform() {
try {
//这个类非常熟悉,是Android中的类
//如果这个类存在并且Android版本大于0就返回一个Android平台对象
Class.forName("android.os.Build");
if (Build.VERSION.SDK_INT != 0) {
return new Android();
}
} catch (ClassNotFoundException ignored) {
}
try {
//如果不是Android平台再查找是否存在
Optional这个类
//该类定义在java.util.这个包下,如果存在说明是Java平台
Class.forName("java.util.Optional");
return new Java8();
} catch (ClassNotFoundException ignored) {
}
//返回默认的平台
return new Platform();
}
/**
* Platform会返回一个用于切换线程的executor对象,这里的Executor只是一个接口而已
* 该Executor用来切换请求结果callback的执行线程,默认返回空
*/
@Nullable
Executor defaultCallbackExecutor() {
return null;
}
CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor != null) {
return new ExecutorCallAdapterFactory(callbackExecutor);
}
return DefaultCallAdapterFactory.INSTANCE;
}
boolean isDefaultMethod(Method method) {
return false;
}
//java8中有一个新的特性就是接口的默认实现,使用default关键字标识
@Nullable
Object invokeDefaultMethod(Method method, Class<?> declaringClass, Object object,
@Nullable Object... args) throws Throwable {
throw new UnsupportedOperationException();
}
static class Java8 extends Platform {
//判断该方法是不是默认的接口实现方法
@Override
boolean isDefaultMethod(Method method) {
return method.isDefault();
}
@Override
Object invokeDefaultMethod(Method method, Class<?> declaringClass, Object object,
@Nullable Object... args) throws Throwable {
Constructor<Lookup> constructor = Lookup.class.getDeclaredConstructor(Class.class, int.class);
constructor.setAccessible(true);
return constructor.newInstance(declaringClass, -1
.unreflectSpecial(method, declaringClass)
.bindTo(object)
.invokeWithArguments(args);
}
}
//Android平台
static class Android extends Platform {
//返回将callback切换到主线程执行的Executor
@Override
public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
//Android平台下默认的CallAdapterFactory为ExecutorCallAdapterFactor
@Override
CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
return new ExecutorCallAdapterFactory(callbackExecutor);
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
//这里使用了handler将runnable任务切换到主线程中执行
@Override
public void execute(Runnable r) {
handler.post(r);
}
}
}
}
step2:通过builder设置参数
Retrofit的Builder提供了几个方法来设置Retrofit的核心参数:
//这几个参数和Retorift中对应
private final Platform platform;
private @Nullable okhttp3.Call.Factory callFactory;
private HttpUrl baseUrl;
private final List<Converter.Factory> converterFactories = new ArrayList<>();
private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
private @Nullable Executor callbackExecutor;
private boolean validateEagerly;
/**
* OkHttpClient本身实现了okhttp3.Call.Factory这个接口,
*一般我们直接使用OkHttp的时候都是直接调用OkHttpClient的newCall()方法来创建一个Call请求
* 这里又会调用callFactory()方法来设置callFactory对象
*/
public Builder client(OkHttpClient client)
/**
* 设置callFactory对象,用来创建call请求
*/
public Builder callFactory(okhttp3.Call.Factory factory)
/**
* 设置请求URL的基础url,该基础url包含{协议://主机:端口号/},这里的基础url末尾需要以/结尾
* 最终该基础url和接口中的url会拼接为一个完整的url,所以retrofit是一个RESTful的网络请求框架
*/
public Builder baseUrl(String baseUrl)
/**
* 添加一个Converter工厂对象,Converter类可以对请求结果按照用户的要求做进一步的转换
*/
public Builder addConverterFactory(Converter.Factory factory)
/**
* 添加一个请求适配器,该适配器会将默认的OkHttpCall转换为其他框架需要的对象,比如转换为一个Observable对象
*/
public Builder addCallAdapterFactory(CallAdapter.Factory factory)
/**
* 设置callback线程切换的executor
*/
public Builder callbackExecutor(Executor executor)
//该标记标识是否提前通过反射构建出接口中定义的方法,默认不提前
public Builder validateEagerly(boolean validateEagerly)
通过以上方法设置好这些参数后通过build()方法创建出了Retrofit对象。
step3:创建Retrofit对象
public Retrofit build() {
//baseurl如果为null抛出异常,所以这个参数一定要设置
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
//如果callactory为null则默认使用OkHttpClient
if (callFactory == null) {
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
//在Android平台下这里返回的就是MainThreadExecutor
callbackExecutor = platform.defaultCallbackExecutor();
}
//在自定义的CallAdapter.Factory后面会再添加一个默认的CallAdapter.Factory
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
//在Android平台下,该默认的CallAdapter.Factory为ExecutorCallAdapterFactory
callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
List<Converter.Factory> converterFactories =
new ArrayList<>(1 + this.converterFactories.size());
// 在自定义Converter.Factory之前会添加一个内置的BinltInConverters对象
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
//创建返回Retrofit对象
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
再有了Retrofit对象后,我们调用了create()方法来创建接口对象。
step4:创建请求接口对象
在使用Retrofit的时候,我们只是定义了一个接口而已,并没有它的实现,一开始我还以为是Retrofit在编译期间来动态生成对应的实现类,通过查看源码发现并不是这样的,而是通过动态代理的方式来创建出这个接口对象,如果不清楚动态代理的观众请自行补习相关内容,这里就不说什么是动态代理了,具体我们查看源码:
public <T> T create(final Class<T> service) {
//判断该service是否是一个符合要求的接口class
//Retrofit要求定义的接口不能继承别的接口
Utils.validateServiceInterface(service);
//如果需要提前构建出接口中的方法,那么这里就会调用loadServiceMethod()方法通过反射的方式
//找到接口中所有定义的方法将其封装为一个ServiceMethod对象并缓存
if (validateEagerly) {
//提前加载ServiceMethod
eagerlyValidateMethods(service);
}
//返回一个请求接口的代理类对象
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[]{service},
new InvocationHandler() {
private final Platform platform = Platform.get();
@Override
public Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
//每当我们调用了接口中的方法,都会走到这个invoke()方法中来
// 如果执行的方法是在Object类中定义的
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
//Android平台下默认为false
//在Java平台下,java8新增了一个特性,接口方法的默认实现,在方法声明上加上default即可
//在定义接口的时候,可以有方法的实现,然后加上default声明就可以了。
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
//解析生成ServiceMethod
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
//创建okHttpCall对象
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
//接着通过callAdapter对call请求做一个转换
return serviceMethod.adapt(okHttpCall);
}
});
}
5、调用接口方法获取请求
通过调用loadServiceMethod()方法,会解析在接口中声明的方法中的注解,将其封装为一个ServiceMethod对象。
ServiceMethod<?, ?> loadServiceMethod(Method method) {
//先从缓存中获取
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
//缓存中没有则创建一个ServiceMethod,然后将其放入缓存中
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
ServieMethod对象也是使用构建者模式来创建的,在ServiceMethod中Builder的构造方法中初始化了如下几个关键参数:
final Retrofit retrofit;
final Method method;
final Annotation[] methodAnnotations;
final Annotation[][] parameterAnnotationsArray;
final Type[] parameterTypes;
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
//获取方法上的所有注解
this.methodAnnotations = method.getAnnotations();
//获方法参数的类型
this.parameterTypes = method.getGenericParameterTypes();
//获取参数上的所有注解
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
最后调用build()方法创建出了ServiceMethod对象,那么肯定在build()方法中做了解析注解等操作,继续跟踪源码查看:
public ServiceMethod build() {
//从Retrofit对象中获取callAdapter对象
callAdapter = createCallAdapter();
//获取call请求对象的返回值类型
responseType = callAdapter.responseType();
//如果返回值类型是Response则抛出异常
if (responseType == Response.class || responseType == okhttp3.Response.class) {
throw methodError("'"
+ Utils.getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
//从Retrofit对象中获取Converter对象,用于将设置的请求体参数转换为一个RequestBody和解析response返回结果
responseConverter = createResponseConverter();
//解析方法上的注解
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
//如果没有在方法上设置请求方法,则抛出类型,比如GET、POST这种注解
if (httpMethod == null) {
throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
}
//如果请求中不能有请求体,比如GET请求方式
if (!hasBody) {
//如果是文件上传,则抛出异常
if (isMultipart) {
throw methodError(
"Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
}
//如果是表单上传,则抛出异常
if (isFormEncoded) {
throw methodError("FormUrlEncoded can only be specified on HTTP methods with "
+ "request body (e.g., @POST).");
}
}
//参数上的注解
int parameterCount = parameterAnnotationsArray.length;
//创建ParameterHandler数组,parameterhandler用于处理参数上的注解
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0; p < parameterCount; p++) {
//方法中参数的类型,和该参数上的注解一一对应
Type parameterType = parameterTypes[p];
if (Utils.hasUnresolvableType(parameterType)) {
throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s",
parameterType);
}
Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
if (parameterAnnotations == null) {
throw parameterError(p, "No Retrofit annotation found.");
}
//解析参数上的注解
parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
}
//以下就是判断一些冲突情况了。
//如果url为空则抛出异常
if (relativeUrl == null && !gotUrl) {
throw methodError("Missing either @%s URL or @Url parameter.", httpMethod);
}
//如果不能有请求体却使用了Body注解抛出异常
if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
throw methodError("Non-body HTTP method cannot contain @Body.");
}
//如果是表单上传却没有Field注解则抛出异常
if (isFormEncoded && !gotField) {
throw methodError("Form-encoded method must contain at least one @Field.");
}
//如果是文件上传却没有使用Part注解,则抛出异常
if (isMultipart && !gotPart) {
throw methodError("Multipart method must contain at least one @Part.");
}
//创建ServiceMethod对象并返回
return new ServiceMethod<>(this);
}
具体是如何解析注解的这里就不看了,都是一些繁琐的事情。
在获取到了ServiceMethod对象后,接着就创建了OkHttpCall对象,OKHttpCall实现了Call接口,这个Call接口不是OkHttp中的Call接口,而是Retrofit内部自己的接口,不过它和OkHttp中的Call的行为是一样的。这里创建的OkHttpCall也只是保存了ServiceMethod对象和该方法的请求参数。
final class OkHttpCall<T> implements Call<T>
在最后则调用了serviceMethod.adapt(okHttpCall)
对call对象进行了适配转换。这里的转换非常重要,如果我们在初始化Retrofit的时候设置了RxJava的callAdapter,那么这里通过适配器转换后则返回的是一个Observable对象。先来瞅一眼RxJavaCallAdapter的adapt方法:
public Object adapt(Call<R> call) {
...
Observable<?> observable = Observable.create(func);
...
return observable;
}
在构造Retrofit对象的时候,如果不设置CallAdapter对象,那么这个callada对象在Android平台下则默认是通过ExecutorCallAdapterFactory来创建的。
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
final Executor callbackExecutor;
//在创建ExecutorCallAdapterFactory对象的时候传递了callbackExecutor对象
ExecutorCallAdapterFactory(Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
//如果返回值不是Call类型,则退出,所以如果我们不是使用RxJava的话,
//我们在定义接口的时候返回值都是Call类型,如果不是call类型的话就返回空,
//在Retrofit中会继续调用其他的CallAdapter.Factory对象来处理
if (getRawType(returnType) != Call.class) {
return null;
}
//请求返回类型,即在接口方法中返回值Call<T>中的这个T类型
final Type responseType = Utils.getCallResponseType(returnType);
//返回一个匿名类
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call<Object> adapt(Call<Object> call) {
//这里返回了一个ExecutorCallbackCall对象
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
//ExecutorCallbackCall实际上是一个包装类,使用了装饰器设计模式
//这里使用装饰器模式的目的是为了异步执行的时候将callback使用executor切换线程来执行
static final class ExecutorCallbackCall<T> implements Call<T> {
final Executor callbackExecutor;
final Call<T> delegate;
ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;
}
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> response) {
//这里看到了callbackExecutor的使用,通过callbackExecutor来切换线程调用callback
callbackExecutor.execute(new Runnable() {
@Override public void run() {
if (delegate.isCanceled()) {
callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
} else {
callback.onResponse(ExecutorCallbackCall.this, response);
}
}
});
}
@Override public void onFailure(Call<T> call, final Throwable t) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
//下面所有的方法都是调用原来的call对象来执行的
@Override public boolean isExecuted() {
return delegate.isExecuted();
}
@Override public Response<T> execute() throws IOException {
return delegate.execute();
}
@Override public void cancel() {
delegate.cancel();
}
@Override public boolean isCanceled() {
return delegate.isCanceled();
}
@SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.
@Override public Call<T> clone() {
return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
}
@Override public Request request() {
return delegate.request();
}
}
}
到这里我们已经清楚了Call请求是如何来的了,而且在ExecutorCallAdapterFactory中会将OkHttpCall转换为一个ExecutorCallbackCall对象,ExecutorCallbackCall是一个包装类,它的功能只是在异步执行请求的时候返回结果时将callback切换到主线程中来执行。那么在调用call的execute或者enqueue方法时会做什么呢,这里的Call并不是OkHttp里面的那个Call,而Retrofit在网路请求的时候还是使用的OkHttp,那么必然有一个地方会将Retrofit创建出来的call请求转换为OkHttp的call。这里就直接贴出OkHttpCall的源码进行分析
final class OkHttpCall<T> implements Call<T> {
//请求的接口方法
private final ServiceMethod<T, ?> serviceMethod;
//请求接口方法中的参数
private final @Nullable Object[] args;
//取消标记
private volatile boolean canceled;
//真正OkHttp中的call请求
private @Nullable okhttp3.Call rawCall;
private @Nullable Throwable creationFailure;
//是否已经执行的标记
private boolean executed;
OkHttpCall(ServiceMethod<T, ?> serviceMethod, @Nullable Object[] args) {
this.serviceMethod = serviceMethod;
this.args = args;
}
@Override public OkHttpCall<T> clone() {
return new OkHttpCall<>(serviceMethod, args);
}
//获取OkHttp中的Request请求
@Override public synchronized Request request() {
okhttp3.Call call = rawCall;
if (call != null) {
return call.request();
}
if (creationFailure != null) {
if (creationFailure instanceof IOException) {
throw new RuntimeException("Unable to create request.", creationFailure);
} else if (creationFailure instanceof RuntimeException) {
throw (RuntimeException) creationFailure;
} else {
throw (Error) creationFailure;
}
}
try {
return (rawCall = createRawCall()).request();
} catch (RuntimeException | Error e) {
throwIfFatal(e); // Do not assign a fatal error to creationFailure.
creationFailure = e;
throw e;
} catch (IOException e) {
creationFailure = e;
throw new RuntimeException("Unable to create request.", e);
}
}
//异步执行请求
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
okhttp3.Call call;
Throwable failure;
synchronized (this) {
//如果该请求已经执行了则抛出异常
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
call = rawCall;
failure = creationFailure;
if (call == null && failure == null) {
try {
//转换为OkHttp中的call
call = rawCall = createRawCall();
} catch (Throwable t) {
throwIfFatal(t);
failure = creationFailure = t;
}
}
}
if (failure != null) {
callback.onFailure(this, failure);
return;
}
//这时的call已经是OkHttp中的call请求了
if (canceled) {
取消请求
call.cancel();
}
//这里就是okhttp中的异步请求执行了
call.enqueue(new okhttp3.Callback() {
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response;
try {
//解析response
response = parseResponse(rawResponse);
} catch (Throwable e) {
callFailure(e);
return;
}
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
t.printStackTrace();
}
}
@Override public void onFailure(okhttp3.Call call, IOException e) {
callFailure(e);
}
private void callFailure(Throwable e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
t.printStackTrace();
}
}
});
}
@Override public synchronized boolean isExecuted() {
return executed;
}
//同步执行
@Override public Response<T> execute() throws IOException {
okhttp3.Call call;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
if (creationFailure != null) {
if (creationFailure instanceof IOException) {
throw (IOException) creationFailure;
} else if (creationFailure instanceof RuntimeException) {
throw (RuntimeException) creationFailure;
} else {
throw (Error) creationFailure;
}
}
call = rawCall;
if (call == null) {
try {
//转换call请求
call = rawCall = createRawCall();
} catch (IOException | RuntimeException | Error e) {
throwIfFatal(e); // Do not assign a fatal error to creationFailure.
creationFailure = e;
throw e;
}
}
}
if (canceled) {
call.cancel();
}
//同步执行并解析response
return parseResponse(call.execute());
}
//转换为OkHttp里面的call 请求,生成来处理转换的还是在ServiceMethod中
private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = serviceMethod.toCall(args);
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
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();
int code = rawResponse.code();
if (code < 200 || code >= 300) {
try {
//如果响应码不在200-300之间
ResponseBody bufferedBody = Utils.buffer(rawBody);
return Response.error(bufferedBody, rawResponse);
} finally {
rawBody.close();
}
}
if (code == 204 || code == 205) {
rawBody.close();
return Response.success(null, rawResponse);
}
ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
try {
//这里才是真正解析响应数据的地方
T body = serviceMethod.toResponse(catchingBody);
return Response.success(body, rawResponse);
} catch (RuntimeException e) {
catchingBody.throwIfCaught();
throw e;
}
}
public void cancel() {
canceled = true;
okhttp3.Call call;
synchronized (this) {
call = rawCall;
}
if (call != null) {
call.cancel();
}
}
@Override public boolean isCanceled() {
if (canceled) {
return true;
}
synchronized (this) {
return rawCall != null && rawCall.isCanceled();
}
}
//不能读取响应体的ResponseBody
static final class NoContentResponseBody extends ResponseBody {
private final MediaType contentType;
private final long contentLength;
NoContentResponseBody(MediaType contentType, long contentLength) {
this.contentType = contentType;
this.contentLength = contentLength;
}
@Override public MediaType contentType() {
return contentType;
}
@Override public long contentLength() {
return contentLength;
}
//只要读取数据就抛出异常
@Override public BufferedSource source() {
throw new IllegalStateException("Cannot read raw response body of a converted body.");
}
}
//会自动捕获在读取响应体数据过程中发生的异常的ResponseBody
static final class ExceptionCatchingRequestBody extends ResponseBody {
private final ResponseBody delegate;
IOException thrownException;
ExceptionCatchingRequestBody(ResponseBody delegate) {
this.delegate = delegate;
}
@Override public MediaType contentType() {
return delegate.contentType();
}
@Override public long contentLength() {
return delegate.contentLength();
}
@Override public BufferedSource source() {
return Okio.buffer(new ForwardingSource(delegate.source()) {
@Override public long read(Buffer sink, long byteCount) throws IOException {
try {
return super.read(sink, byteCount);
} catch (IOException e) {
thrownException = e;
throw e;
}
}
});
}
@Override public void close() {
delegate.close();
}
void throwIfCaught() throws IOException {
if (thrownException != null) {
throw thrownException;
}
}
}
}
透过源码可以看到OkHttpCall的工作非常简单,它在这里起到一个承上启下的作用,它还是调用的是OkHttp中的call来执行任务的,而转换为一个OkHttp框架中的Call对象,然后对响应结果进行解析处理,这两个地方真正实现的地方还是在ServiceMethod当中。
//将OkHttpCall转换为一个真正的OkHttp框架中的call,实际上就是通过callFactory来创建了一个call对象
//各位客官如何对OkHttp比较熟悉的话应该对这几行代码非常熟悉,就是我们在使用OkHttp的时候的几个主要步骤
okhttp3.Call toCall(@Nullable Object... args) throws IOException {
//通过RequestBuilder来构建一个Request请求
RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl, headers,
contentType, hasBody, isFormEncoded, isMultipart);
//参数的个数要和ParameterHandler数组个数一致
int argumentCount = args != null ? args.length : 0;
if (argumentCount != handlers.length) {
throw new IllegalArgumentException("Argument count (" + argumentCount
+ ") doesn't match expected count (" + handlers.length + ")");
}
for (int p = 0; p < argumentCount; p++) {
handlers[p].apply(requestBuilder, args[p]);
}
//通过newCall来创建一个Call请求
//在最开始的时候我们看到callFactory默认情况下就是OkHttp
return callFactory.newCall(requestBuilder.build());
}
//解析响应结果,使用的是Converter这个对象
R toResponse(ResponseBody body) throws IOException {
return responseConverter.convert(body);
}
这里的RequestBuilder也起到了承上启下的作用,它里面包含了在接口方法注解上设置的参数,在它的build()中会通过OkHttp的RequestBuilder来构建出OkHttp中的reqeust对象,然后通过newCall方法,将request请求作为参数就创建出了OkHttp中的call对象。RequestBuilder里面都死构建request请求的过程,就不查看它的源码了,它的实现也是非常简单的。
在ServiceMethod中有一个toResponse()方法,它可以将响应的结果解析为我们需要的数据格式,比如我们在创建Retrofit对象的时候设置了GsonConverterFactory,那么这里就会使用gson来解析数据生成我们设置好的数据类型。
通过以上分析我们就清楚了Retrofit的整体执行流程了,有了请求对象后,不管是同步还是异步执行都会走到OkHttp里面去了,到此对Retrofit的分析就结束了。