RxJava2CallAdapter同步异步

613 阅读2分钟

 之前面试有问到RxJava2CallAdapter默认创建的observables是异步的还是同步的这个问题,接下来我们看代码

retrofit = Retrofit.Builder()
                .baseUrl(AppBuildConfig.getHostUrl())
                .addConverterFactory(ResponseConverterFactory)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .addCallAdapterFactory(CoroutineCallAdapterFactory.invoke())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())//此处
                .client(providerHttpClient()).build()

通常我们都是这么引入RxJava2CallAdapter的,我们进去看下

 /**
   * Returns an instance which creates synchronous observables that do not operate on any scheduler
   * by default.
   */

  public static RxJava2CallAdapterFactory create() {
    return new RxJava2CallAdapterFactory(null, false);
  }

  /**
   * Returns an instance which creates asynchronous observables. Applying
   * {@link Observable#subscribeOn} has no effect on stream types created by this factory.
   */
  public static RxJava2CallAdapterFactory createAsync() {
    return new RxJava2CallAdapterFactory(null, true);
  }

通过注释和代码可以看到create方法创建是同步的observables,此时需要线程切换。

observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())

如果我们通过  addCallAdapterFactory(RxJava2CallAdapterFactory.createAsync())

这时就不需要切换到子线程去进行网络访问了,如下

observable.observeOn(AndroidSchedulers.mainThread())

这时只要切换到ui线程即可。接下来我们深入方法内部看下原因

private RxJava2CallAdapterFactory(@Nullable Scheduler scheduler, boolean isAsync) {
    this.scheduler = scheduler;
    this.isAsync = isAsync;
  }

这是构造函数接下来看下get方法

@Override public @Nullable CallAdapter<?, ?> get(
      Type returnType, Annotation[] annotations, Retrofit retrofit) {
...
 return new RxJava2CallAdapter(responseType, scheduler, isAsync, isResult, isBody, isFlowable,
        isSingle, isMaybe, false);
  }
}


final class RxJava2CallAdapter<R> implements CallAdapter<R, Object> {
    private final Type responseType;
    @Nullable
    private final 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;
    }

    public Type responseType() {
        return this.responseType;
    }

    public Object adapt(Call<R> call) {
//此处可以看到同步的创建的是CallExecuteObservable,异步创建的是CallEnqueueObservable
        Observable<Response<R>> responseObservable = this.isAsync ? new CallEnqueueObservable(call)
 : new CallExecuteObservable(call);
        Object observable;
        if (this.isResult) {
            observable = new ResultObservable((Observable)responseObservable);
        } else if (this.isBody) {
            observable = new BodyObservable((Observable)responseObservable);
        } else {
            observable = responseObservable;
        }

        if (this.scheduler != null) {
            observable = ((Observable)observable).subscribeOn(this.scheduler);
        }

        if (this.isFlowable) {
            return ((Observable)observable).toFlowable(BackpressureStrategy.LATEST);
        } else if (this.isSingle) {
            return ((Observable)observable).singleOrError();
        } else if (this.isMaybe) {
            return ((Observable)observable).singleElement();
        } else {
            return this.isCompletable ? ((Observable)observable).ignoreElements() : RxJavaPlugins.onAssembly((Observable)observable);
        }
    }
}

接下来看下CallEnqueueObservable

final class CallEnqueueObservable<T> extends Observable<Response<T>> {
  private final Call<T> originalCall;

  CallEnqueueObservable(Call<T> originalCall) {
    this.originalCall = originalCall;
  }

  @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);
    if (!callback.isDisposed()) {
此处
      call.enqueue(callback);
    }
  }
}}

上面可以看到主动调用了call.enqueue方法。此时会走okhttp的异步处理。所以就不需要切换到io线程了。

接下来看CallExecuteObservable

final class CallExecuteObservable<T> extends Observable<Response<T>> {
  private final Call<T> originalCall;

  CallExecuteObservable(Call<T> originalCall) {
    this.originalCall = originalCall;
  }

  @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();
    CallDisposable disposable = new CallDisposable(call);
    observer.onSubscribe(disposable);
    if (disposable.isDisposed()) {
      return;
    }

    boolean terminated = false;
    try {
//这里调用的是execute
      Response<T> response = call.execute();
      if (!disposable.isDisposed()) {
        observer.onNext(response);
      }
      if (!disposable.isDisposed()) {
        terminated = true;
        observer.onComplete();
      }
    } catch (Throwable t) {
      Exceptions.throwIfFatal(t);
      if (terminated) {
        RxJavaPlugins.onError(t);
      } else if (!disposable.isDisposed()) {
        try {
          observer.onError(t);
        } catch (Throwable inner) {
          Exceptions.throwIfFatal(inner);
          RxJavaPlugins.onError(new CompositeException(t, inner));
        }
      }
    }
  }

上面可以看出直接调用的execute,并没有进行线程切换,所以需要在retrofit进行线程切换。