Retrofit2源码分析(2) CallAdapter详解
Retrofit源码分析基于2.4.0。
本章节中将对Retrofit2中的CallAdapter机制做详细讲解。
在上一章节中曾提到了Call对象的创建是通过是通过ServiceMethod.adapt()完成的,这里在看看该方法的源码:
ServiceMethod.adapt()方法:
T adapt(Call<R> call) {
return callAdapter.adapt(call);
}
通过上述源码可知,最终Call对象是调用CallAdapter.adapt(Call)方法创建的,那么CallAdapter及具体的Call对象又是如何生成的呢?
带着这个疑问开始本章节。
Platform介绍
在上一章节Retrofit创建过程中知道,Retrofit创建时需要获取一个Platform对象,用于指定Retrofit运行的平台,这里我们看下Platform类,如下:
class Platform {
// 1、创建Platform实例
private static final Platform PLATFORM = findPlatform();
// 2、获取Platform实例
static Platform get() {
return PLATFORM;
}
// 3、创建Platform实例
private static Platform findPlatform() {
try {
// 通过反射查找是否存在Android平台的类,
Class.forName("android.os.Build");
if (Build.VERSION.SDK_INT != 0) {
return new Android();
}
} catch (ClassNotFoundException ignored) {
}
try {
Class.forName("java.util.Optional");
return new Java8();
} catch (ClassNotFoundException ignored) {
}
return new Platform();
}
// 获取默认的回调执行器
@Nullable Executor defaultCallbackExecutor() {
return null;
}
// 获取默认CallAdapter.Factory
CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor != null) {
return new ExecutorCallAdapterFactory(callbackExecutor);
}
return DefaultCallAdapterFactory.INSTANCE;
}
boolean isDefaultMethod(Method method) {
return false;
}
@Nullable Object invokeDefaultMethod(Method method, Class<?> declaringClass, Object object,
@Nullable Object... args) throws Throwable {
throw new UnsupportedOperationException();
}
}
从上面Platform的findPlatform()方法可知,Retrofit中支持Android和Java8两个平台。
我们看下Android平台的具体逻辑实现,也就是Platform.Android类:
static class Android extends Platform {
// 1、获取默认的线程执行器,这里是主线程
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
// 2、获取默认的Factory
@Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
// 返回一个默认的Factory,也就是ExecutorCallAdapterFactory
return new ExecutorCallAdapterFactory(callbackExecutor);
}
// 3、主线程回调执行器,用于完成线程切换
static class MainThreadExecutor implements Executor {
// 创建主线程Handler,
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
// 线程切换。
handler.post(r);
}
}
}
在Platform.Android中复写了defaultCallAdapterFactory()和defaultCallbackExecutor()方法,这两个方法分别返回了一个默认的工厂和默认的主线程回调执行器。
这里可以明确下:在Android平台上默认的CallAdapter.Factory就是通过上面的defaultCallAdapterFactory()方法设置的,也就是说Android中默认的CallAdapter.Factory就是ExecutorCallAdapterFactory。
设置默认CallAdapterFactory
在Retrofit中默认的CallAdapter.Factory又是如何指定的呢?
这里我们看下Retrofit的创建过程,也就是Retrofit.Builder.build()方法,如下:
public void build(){
// 省略部分代码
// 1、获取一个Executor执行器
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// 2、初始化一个工厂集合,用于存放所有的CallAdapterFactory
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
// 3、添加默认CallAdapterFactory
callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
// 省略部分代码
}
很清楚了吧,在Retrofit创建时会从Platform对象中获取默认的CallAdapter.Factory并设置,在Android平台中这个Factory就是指ExecutorCallAdapterFactory。
CallAdapter初始化
既然知道了Retrofit中默认的CallAdapter.Factory的是ExecutorCallAdapterFactory,那么接下来就需要看下ExecutorCallAdapterFactory是如何实现CallAdapter的创建的。
这里,再次看下ServiceMethod的adapt()方法中,如下:
T adapt(Call<R> call) {
return callAdapter.adapt(call);
}
在ServiceMethod中CallAdapter对象的初始化是在ServiceMethod.Builder.build()方法中通过调用createCallAdapter()方法实现的。
createCallAdapter()方法:
private CallAdapter<T, R> createCallAdapter() {
// 1、获取接口方法的返回值类型
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(
"Method return type must not include a type variable or wildcard: %s", returnType);
}
if (returnType == void.class) {
throw methodError("Service methods cannot return void.");
}
// 2、获取该方法中所有的注解
Annotation[] annotations = method.getAnnotations();
try {
// 3、获取CallAdapter对象,这个最终会通过工厂类Factory.get()方法实现,默认工行就是ExecutorCallAdapterFactory
return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(e, "Unable to create call adapter for %s", returnType);
}
}
在上面createCallAdapter()方法中最终会通过调用Retrofit.callAdapter()方法获取具体的CallAdapter.
这里看下Retrofit中callAdapter()方法:
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
checkNotNull(returnType, "returnType == null");
checkNotNull(annotations, "annotations == null");
int start = callAdapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
// 1、通过遍历的方式在工厂集合中根据网络接口定义的返回值类型找到合适的工厂。
// 2、通过指定工厂的get()方法获取具体CallAdapter
CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
// 省略部分代码
}
最终,CallAdapter会在Retrofit.nextCallAdapter()方法实现,该方法的功能主要就是:根据参数中网络接口的具体返回值类型找到对应的CallAdpater.Factory并最终通过调用Factory.get()方法获取CallAdapter对象。
ExecutorCallAdapterFactory类
在上文中对CallAdapter.Factory创建CallAdapter对象的流程做了具体分析,这里我们就要看下CallAdapter是如何创建Call对象的。
通过ServiceMethod.adapt()方法可知,CallAdapter获取具体Call主要是通过CallAdapter.adpat()方法实现的。
这里我们以默认的工厂ExecutorCallAdapterFactory生成的CallAdapter做具体分析下。
ExecutorCallAdapterFactory的源码如下:
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
final Executor callbackExecutor;
// 1、创建一个ExecutorCallAdapterFactory对象,指定主线程回调执行器
ExecutorCallAdapterFactory(Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}
// 2、通过该刚发返回具体的CallAdapter对象
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
// 获取网络接口接口返回类型
final Type responseType = Utils.getCallResponseType(returnType);
// 创建一个CallAdapter实例
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
// CallAdapter调用该方法返回具体Call实例
@Override public Call<Object> adapt(Call<Object> call) {
// 创建具体的Call对象,这里是ExecutorCallbackCall
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
// ExecutorCallbackCall类,该类中使用了委托模式
static final class ExecutorCallbackCall<T> implements Call<T> {
final Executor callbackExecutor;
// 在动态代理类创建过程中,delegate就是指OkHttpCall对象
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.execute(new Runnable() {
@Override public void run() {
if (delegate.isCanceled()) {
// Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
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);
}
});
}
});
}
@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();
}
}
}
在ExecutorCallAdapterFactory类中,主要就是复写了get()方法,在该方法中创建一个具体的CallAdpater对象并返回,而在该CallAdapter中adapt()方法创建了一个ExecutorCallbackCall的实例。
ExecutorCallbackCall是ExecutorCallAdapterFactory中定义的内部类,该类继承自Call对象,在该类中对重写了Call的enqueue()、execute()方法。
所以,最终我们执行网络接口方法时,实际上就是通过ExecutorCallbackCall实现的。
不明白的话,看下上章节基本使用中的示例代码,如下:
ILoginService loginService = retrofit.create(ILoginService.class);
//这个call对象实际就是ExecutorCallbackCall对象。
Call<User> call = loginService.login(user);
这里,我们需要注意的是ExecutorCallbackCall异步方法,如下:
// 实现异步请求
@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.execute(new Runnable() {
@Override public void run() {
if (delegate.isCanceled()) {
// Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
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);
}
});
}
});
}
在ExecutorCallbackCall中主要使用代理模式,在该类中持有一个OkHttpCall的实例,网络请求的实际过程都是在OkHttpCall中完成的。
在获取网络响应结果后,在ExecutorCallbackCall中会通过callbackExecutor实现线程切换,这里的callbackExecutor就是Platform.Android中定义的MainThreadExecutor也就是主线程回调执行器。最终我们的回调方法会在主线程中执行。
这就是为什么Retrofit异步请求回调方法在主线程中被调用的原因。
总结
关于CallAdapter的讲解就到此为止了。
其实在Retrofit中支持自定义CallAdapter.Factory实现自定义CallAdapter的功能。比如最流行的RxJava2CallAdapterFactory,通过RxJava2CallAdapterFactory可以实现Rxjava和Retrofit的结合,有兴趣的同学可以自行了解下。