retrofit的CallAdapter和GsonConvert

剛開始學(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);
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前言 在Android開發(fā)中,網(wǎng)絡(luò)請求十分常用 而在Android網(wǎng)絡(luò)請求庫中,Retrofit是當(dāng)下最熱的一個網(wǎng)...
    053999cbda34閱讀 413評論 0 0
  • 簡介 剛接觸Retrofit的時候,就寫了一篇簡單的使用介紹:Retrofit 2.0基本使用方法,算是對Retr...
    Whyn閱讀 3,111評論 4 24
  • 前言 之前講過了okhttp的超級概括的原理解析,okhttp以它優(yōu)秀的線程池設(shè)計,任務(wù)隊列的分配和轉(zhuǎn)化以及基于責(zé)...
    Dex_閱讀 240評論 0 1
  • 我們雖然窮,但是不能說謊,也不能打人,不是我們的東西,我們不能拿,要好好讀書,長大要做個對社會有用的人?!薄堕L...
    尹天酬閱讀 677評論 0 1
  • 一、Retrofit簡介 Retrofit是現(xiàn)下Android端開發(fā)非常流行的一款網(wǎng)絡(luò)請求框架,它通過動態(tài)代理的方...
    愛恨流星閱讀 744評論 0 0

友情鏈接更多精彩內(nèi)容