本文參考 Retrofit分析-漂亮的解耦套路
圖片來源 Retrofit分析-漂亮的解耦套路
源碼版本:Retrofit2.4.0 Rxjava2 2.2.0
Refrofit流程圖

我們根據(jù)這張流程圖來對著源碼慢慢來看。一切從左上角開始。
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的動態(tài)代理功能。實現(xiàn)InvocationHandler接口即可。通過loadServiceMethod()代理生成傳入Service的代理類ServiceMethod。下方的OkHttpCall是OKhttp3的封裝類。最后通過serviceMethod.adapt(okHttpCall)將okHttpCall設(shè)置回serviceMethod中,以便之后在各種CallAdapter中使用。callAdapter是一個適配器,適配成其他平臺可以使用的類型,比如轉(zhuǎn)化為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()方法,他設(shè)置了緩存池,自身是通過ServiceMethod.Builder()建造者來生成,此方法將收集傳入的service方法包含的注解信息以及在Retrofit.Builder()方法中配置的BaseUrl,okHttpClient,Converter,CallAdapter并將其轉(zhuǎn)化為參數(shù)設(shè)置到result中。此時我們傳入的service中所有數(shù)據(jù)都已經(jīng)裝配完畢了。此時上圖中我們已經(jīng)進行到了圖中CallAdapter.adapt。由上述代碼我們可知retrofit.create({service}).{service.method}.實際調(diào)用的是callAdapter.adapt(call)。
2.CallAdapter.adapt(call)

完成了以上配置工作,接下來就要開始動手干活了。CallAdapter有四個實現(xiàn)類,以現(xiàn)在的最常用的Rxjava2.2.0 + Retrofit2.4.0模式為例,所以最終調(diào)用的是RxJava2CallAdapter中的adapt方法。(當(dāng)然RxJava2CallAdapter在頂部圖片是已經(jīng)沒有了)
@Override public Object adapt(Call<R> call) {
Observable<Response<R>> responseObservable = isAsync
? new CallEnqueueObservable<>(call)
: new CallExecuteObservable<>(call);
...
}
上述代碼中CallEnqueueObservable與CallExecuteObservable對應(yīng)Okhttp中的異步請求和同步請求。這里通過RxJava2CallAdapterFactory.create()/createAsync()去設(shè)置,本質(zhì)是改變Okhttp請求方法來控制同步異步,但是現(xiàn)在很多做法是通過Rxjava2去調(diào)度使用的時候去調(diào)度線程,所以可以看到很多庫封裝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中調(diào)用。其中CallCallback是連接Retrofit,Rxjava2,OKhttp的橋梁,Okhttp產(chǎn)生回調(diào)后會傳回Retrofit,最終通知Rxjava2。這里也走到了最終網(wǎng)絡(luò)請求的方法call.enqueue(callback),點進去我們就可以看到熟悉的OKHttp的網(wǎng)絡(luò)方法。
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)中設(shè)置的callback,就此回到Retrofit的回調(diào)。在CallCallback.onResponse中又有observer.onNext(response)最后回到了Rxjava2。至此流程結(jié)束。接下來就全部是Rxjava2的事兒了。
5.總結(jié)
Retrofit2在靈活解耦方面做的十分精妙,需要多看幾次學(xué)習(xí)學(xué)習(xí)其中的思想。如果文章中描述有誤,歡迎在留言中指出。