尊重他人的勞動成果,轉載請標明出處:http://blog.csdn.net/gengqiquan/article/details/52785773, 本文出自:【gengqiquan的博客】
上篇博客Retrofit源碼解析我們講到了retrofit所採用的註解方法會交由ServiceMethod的callAdapter 去進行層層適配,然後交由OkHttpCall 去執行具體的請求 並且這個callAdapter 是可以設置的。使用rxjava的用戶一般會設置RxJavaCallAdapterFactory.create())而如果用戶如果不設置的話,retrofit會默認創建一個。
創建過程就在之前的retrofit的build()方法裏
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
可以看到採用的是默認的ExecutorCallAdapterFactory,這個適配工廠比較簡單,就是直接把用回調傳遞響應結果
@Override
public CallAdapter<Call<?>> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter<Call<?>>() {
@Override public Type responseType() {
return responseType;
}
@Override public <R> Call<R> adapt(Call<R> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
他的adapt方法裏構建了一個回調執行器
@Override public void enqueue(final Callback<T> callback) {
if (callback == null) throw new NullPointerException("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);
}
});
}
});
}
//這裏省略了一大批代理實際請求的方法
}
可以看到實際請求成功後會傳給callbackExecutor自身的回調,這個套路和我們正常封裝網絡請求的套路一樣,多包裹一層回調,再利用靜態代理調用實際請求的回調方法,將結果傳遞給自己的回調,好處是所有自己實現的解析類都只需要按照這個套路來就可以了,而不需要去關注實際call執行的內部邏輯。並且框架使用者也無法去幹預框架內部的邏輯,解耦的相當徹底,這算是第二道菜吧。
上面是retrofit框架自帶的解析類,下面我們來看看基於rxjava實現的解析類,retrofit作爲一個網絡框架而言,全面而強大自不用多說,但他真正吸引我和許多開發者卻是他與rxjava的無縫對接。那麼如果我們搞清楚這個無縫對接的過程,是不是就可以不用retrofit而讓自己原本的網絡框架也實現和retrofit的無縫對接呢?答案是肯定的。
@Override
public CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
//省略一堆代碼
if (isCompletable) {
// Add Completable-converter wrapper from a separate class. This defers classloading such that
// regular Observable operation can be leveraged without relying on this unstable RxJava API.
// Note that this has to be done separately since Completable doesn't have a parametrized
// type.
return CompletableHelper.createCallAdapter(scheduler);
}
CallAdapter<Observable<?>> callAdapter = getCallAdapter(returnType, scheduler);
if (isSingle) {
// Add Single-converter wrapper from a separate class. This defers classloading such that
// regular Observable operation can be leveraged without relying on this unstable RxJava API.
return SingleHelper.makeSingle(callAdapter);
}
return callAdapter;
}
三種返回,我們看第二種
private CallAdapter<Observable<?>> getCallAdapter(Type returnType, Scheduler scheduler) {
Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
Class<?> rawObservableType = getRawType(observableType);
if (rawObservableType == Response.class) {
if (!(observableType instanceof ParameterizedType)) {
throw new IllegalStateException("Response must be parameterized"
+ " as Response<Foo> or Response<? extends Foo>");
}
Type responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
return new ResponseCallAdapter(responseType, scheduler);
}
if (rawObservableType == Result.class) {
if (!(observableType instanceof ParameterizedType)) {
throw new IllegalStateException("Result must be parameterized"
+ " as Result<Foo> or Result<? extends Foo>");
}
Type responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
return new ResultCallAdapter(responseType, scheduler);
}
return new SimpleCallAdapter(observableType, scheduler);
}
依舊三種返回,每種callAdapter的實現裏都實現了adapt,也就是我們retrofit代理的那個方法,我們隨便看一個,其實思路是一樣的,都是通過rxjava的創建操作符創建Observable
static final class ResultCallAdapter implements CallAdapter<Observable<?>> {
private final Type responseType;
private final Scheduler scheduler;
ResultCallAdapter(Type responseType, Scheduler scheduler) {
this.responseType = responseType;
this.scheduler = scheduler;
}
@Override public Type responseType() {
return responseType;
}
@Override public <R> Observable<Result<R>> adapt(Call<R> call) {
Observable<Result<R>> observable = Observable.create(new CallOnSubscribe<>(call)) //
.map(new Func1<Response<R>, Result<R>>() {
@Override public Result<R> call(Response<R> response) {
return Result.response(response);
}
}).onErrorReturn(new Func1<Throwable, Result<R>>() {
@Override public Result<R> call(Throwable throwable) {
return Result.error(throwable);
}
});
if (scheduler != null) {
return observable.subscribeOn(scheduler);
}
return observable;
}
}
通過map轉換符把call的response轉換回了自定義的Result的response,然後在恰當的地方將Observable傳遞下去,然後我們就可以在請求執行成功後拿到框架返回給我們的Observable開心的進行操作了。
以上就是RxJavaCallAdapterFactory做的事了
關於ConverterFactory,其實裏面東西更少就是把返回的值轉換爲我們設定的對象類型。通過Retrofit自定義Converter之StringConverterFactory應該可以看出來ConverterFactory的一般實現套路了。
對了,本人收藏了一份詳細的rxjava教程。嘿嘿,想要的可以到羣裏要。
我建了一個QQ羣(羣號:121606151),用於大家討論交流Android技術問題,有興趣的可以加下,大家一起進步。