Retrofit 2.4.0 工作流程源码解析
本文参考 Retrofit分析-漂亮的解耦套路
图片来源 Retrofit分析-漂亮的解耦套路
源码版本:Retrofit2.4.0 Rxjava2 2.2.0
Refrofit流程图
Retrofit原理我们根据这张流程图来对着源码慢慢来看。一切从左上角开始。
1.retrofit.create(service.class)
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
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 {
// If the method is a method from Object then defer to normal invocation.
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.adapt(okHttpCall);
}
});
}
这里主要用到了JDK的动态代理功能。实现InvocationHandler接口即可。通过loadServiceMethod()代理生成传入Service的代理类ServiceMethod。下方的OkHttpCall是OKhttp3的封装类。最后通过serviceMethod.adapt(okHttpCall)将okHttpCall设置回serviceMethod中,以便之后在各种CallAdapter中使用。callAdapter是一个适配器,适配成其他平台可以使用的类型,比如转化为Rxjava或者Rxjava2。
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
这里回头再看下loadServiceMethod()方法,他设置了缓存池,自身是通过ServiceMethod.Builder()建造者来生成,此方法将收集传入的service方法包含的注解信息以及在Retrofit.Builder()方法中配置的BaseUrl,okHttpClient,Converter,CallAdapter并将其转化为参数设置到result中。此时我们传入的service中所有数据都已经装配完毕了。此时上图中我们已经进行到了图中CallAdapter.adapt。由上述代码我们可知retrofit.create({service}).{service.method}.实际调用的是callAdapter.adapt(call)。
2.CallAdapter.adapt(call)
CallAdapter实现类完成了以上配置工作,接下来就要开始动手干活了。CallAdapter有四个实现类,以现在的最常用的Rxjava2.2.0 + Retrofit2.4.0模式为例,所以最终调用的是RxJava2CallAdapter中的adapt方法。(当然RxJava2CallAdapter在顶部图片是已经没有了)
@Override public Object adapt(Call<R> call) {
Observable<Response<R>> responseObservable = isAsync
? new CallEnqueueObservable<>(call)
: new CallExecuteObservable<>(call);
...
}
上述代码中CallEnqueueObservable与CallExecuteObservable对应Okhttp中的异步请求和同步请求。这里通过RxJava2CallAdapterFactory.create()/createAsync()去设置,本质是改变Okhttp请求方法来控制同步异步,但是现在很多做法是通过Rxjava2去调度使用的时候去调度线程,所以可以看到很多库封装Retrofit是使用RxJava2CallAdapterFactory.create()的。但是我们这里还是着重看下异步请求。
3.CallEnqueueObservable
final class CallEnqueueObservable<T> extends Observable<Response<T>> {
....
@Override protected void subscribeActual(Observer<? super Response<T>> observer) {
// Since Call is a one-shot type, clone it for each new observer.
Call<T> call = originalCall.clone();
CallCallback<T> callback = new CallCallback<>(call, observer);
observer.onSubscribe(callback);
call.enqueue(callback);
}
private static final class CallCallback<T> implements Disposable, Callback<T> {
....
CallCallback(Call<?> call, Observer<? super Response<T>> observer) {
this.call = call;
this.observer = observer;
}
@Override public void onResponse(Call<T> call, Response<T> response) {
if (call.isCanceled()) return;
try {
observer.onNext(response);
if (!call.isCanceled()) {
terminated = true;
observer.onComplete();
}
} catch (Throwable t) {
....
}
}
}
}
@Override public void onFailure(Call<T> call, Throwable t) {
....
}
...
}
CallEnqueueObservable重写了subscribeActual,subscribeActual会在subscribe中调用。其中CallCallback是连接Retrofit,Rxjava2,OKhttp的桥梁,Okhttp产生回调后会传回Retrofit,最终通知Rxjava2。这里也走到了最终网络请求的方法call.enqueue(callback)
,点进去我们就可以看到熟悉的OKHttp的网络方法。
4.call.enqueue(new okhttp3.Callback()
call.enqueue(new okhttp3.Callback() {
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response;
try {
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();
}
}
});
}
在call.enqueue中还看到中callback.onResponse(OkHttpCall.this, response)
和callback.onFailure(OkHttpCall.this, e)
此处的callback就是observer.onSubscribe(callback)
中设置的callback,就此回到Retrofit的回调。在CallCallback.onResponse中又有observer.onNext(response)最后回到了Rxjava2。至此流程结束。接下来就全部是Rxjava2的事儿了。
5.总结
Retrofit2在灵活解耦方面做的十分精妙,需要多看几次学习学习其中的思想。如果文章中描述有误,欢迎在留言中指出。