剛開始學(xué)Retrofit的時候?qū)allAdapterFactory和GsonConvert總是搞不清楚,現(xiàn)在總結(jié)下:
CallAdapterFactory
DefaultCallAdapterFactory
CallAdapterFactory生產(chǎn)CallAdapter,CallAdapter的作用是將網(wǎng)絡(luò)返回的數(shù)據(jù)進(jìn)行拿到的時候,我們在這里還有一次機(jī)會對數(shù)據(jù)進(jìn)行處理(數(shù)據(jù)處理或線程處理)。
Retrofit寫了一個默認(rèn)的CallAdapter,該adapter幫我們切換了線程,切到了Android的主線程。
具體是DefaultCallAdapterFactory.get()返回的那個匿名類:
final class DefaultCallAdapterFactory extends CallAdapter.Factory {
private final @Nullable Executor callbackExecutor;
DefaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}
@Override
public @Nullable CallAdapter<?, ?> get(
...
final Executor executor =
Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)
? null
: callbackExecutor;
//就是下面這個!
return new CallAdapter<Object, Call<?>>() {
@Override
public Type responseType() {
return responseType;
}
@Override
public Call<Object> adapt(Call<Object> call) {
return executor == null ? call : new ExecutorCallbackCall<>(executor, call);
}
};
}
...
}
具體retrofit如何使用這個類的:
retrofit在create()方法的時候通過動態(tài)代理生成了實現(xiàn)我們api接口的類,所以會統(tǒng)一調(diào)到代理方法loadServiceMethod(method).invoke(args)。
loadServiceMethod方法返回了一個CallAdapted對象。
CallAdapted 繼承 HttpServiceMethod 繼承 ServiceMethod。
但傳入的這個CallAdapted其實也是個殼兒,因為CallAdapted內(nèi)部持有一個callAdapter,需要在構(gòu)造方法中傳入。
而這次
loadServiceMethod中傳入的call Adapter就是從默認(rèn)的callAdapterFactory是DefaultCallAdapterFactory,它的get方法返回的就是上面寫的默認(rèn)的CallAdapter(匿名內(nèi)部類)。
invoke方法在HttpServiceMethod中:
@Override
final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
adapt方法在CallAdapted自己里面:
static final class CallAdapted<ResponseT, ReturnT> extends HttpServiceMethod<ResponseT, ReturnT> {
private final CallAdapter<ResponseT, ReturnT> callAdapter;
CallAdapted(...,CallAdapter<ResponseT, ReturnT> callAdapter) {
super(...);
this.callAdapter = callAdapter;
}
@Override
protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
return callAdapter.adapt(call);
}
}
所以調(diào)用的就是外面?zhèn)鬟M(jìn)來的adapterd.adapt方法。返回值是 new ExecutorCallbackCall<>(executor, call)
executor是構(gòu)造方法中傳入的callbackExecutor,實際在Android中是MainThreadExecutor,原來就是主線程。
static final class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override
public void execute(Runnable r) {
handler.post(r);
}
}
而具體返回的ExecutorCallbackCall 和 原先的Call比起來,也就是切了個線程的意思:
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) {
delegate.enqueue(
new Callback<T>() {
@Override
public void onResponse(Call<T> call, final Response<T> response) {
callbackExecutor.execute(
() -> {
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(() -> callback.onFailure(ExecutorCallbackCall.this, t));
}
});
}
...
}
RxJava2CallAdapterFactory
所以直接看RxJava2CallAdapterFactory的get方法返回就好了,返回的是個RxJava2CallAdapter:
final class RxJava2CallAdapter<R> implements CallAdapter<R, Object> {
private final Type responseType;
private final @Nullable Scheduler scheduler;
private final boolean isAsync;
private final boolean isResult;
private final boolean isBody;
private final boolean isFlowable;
private final boolean isSingle;
private final boolean isMaybe;
private final boolean isCompletable;
RxJava2CallAdapter(Type responseType, @Nullable Scheduler scheduler, boolean isAsync,
boolean isResult, boolean isBody, boolean isFlowable, boolean isSingle, boolean isMaybe,
boolean isCompletable) {
this.responseType = responseType;
this.scheduler = scheduler;
this.isAsync = isAsync;
this.isResult = isResult;
this.isBody = isBody;
this.isFlowable = isFlowable;
this.isSingle = isSingle;
this.isMaybe = isMaybe;
this.isCompletable = isCompletable;
}
@Override public Type responseType() {
return responseType;
}
//所以直接看adapt方法就好了,就是返回的call改成RxJava里面的流了
@Override public Object adapt(Call<R> call) {
Observable<Response<R>> responseObservable = isAsync
? new CallEnqueueObservable<>(call)
: new CallExecuteObservable<>(call);
Observable<?> observable;
if (isResult) {
observable = new ResultObservable<>(responseObservable);
} else if (isBody) {
observable = new BodyObservable<>(responseObservable);
} else {
observable = responseObservable;
}
if (scheduler != null) {
observable = observable.subscribeOn(scheduler);
}
if (isFlowable) {
return observable.toFlowable(BackpressureStrategy.LATEST);
}
if (isSingle) {
return observable.singleOrError();
}
if (isMaybe) {
return observable.singleElement();
}
if (isCompletable) {
return observable.ignoreElements();
}
return observable;
}
}
其實retrofit自帶還有一個CompletableFutureCallAdapterFactory 和 CompletableFutureCallAdapterFactory,對應(yīng)的是java8里面的流,有興趣可以看下。
GsonConvert
GsonConvert主要作用是將json轉(zhuǎn)成實體對象。在那作用的呢?
注意invoke方法中返回的是個OkHttpCall對象,所以每次拿這個call.enqueue()的時候,其實是okHttpCall.enqueue方法:
@Override
public void enqueue(final Callback<T> callback) {
...
call = rawCall;//真正的okhttp包下的call
call.enqueue(
new okhttp3.Callback() {
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response;
try {
//關(guān)鍵這行
response = parseResponse(rawResponse);
} catch (Throwable e) {
throwIfFatal(e);
callFailure(e);
return;
}
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
throwIfFatal(t);
t.printStackTrace(); // TODO this is not great
}
}
@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) {
throwIfFatal(t);
t.printStackTrace(); // TODO this is not great
}
}
});
}
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
...
//就是在這被調(diào)用的
T body = responseConverter.convert(catchingBody);
}