Retrofit 源码分析6-Rxjava2CallAdapter 是如何适配的

时间:2021-7-4 作者:qvyue

创建完 OkHttpCall 对象后,以 RxJava2CallAdapter 为例,会调用 adapt 方法进行接下去的操作。这个方法的逻辑控制是通过一些变量值进行的,所以要先了解下各个变量值。

@Override public Object adapt(Call call) {
    Observable> 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 RxJavaPlugins.onAssembly(observable);
}

变量值会在构造方法里赋值,所以要去看下该适配器的创建,在 HttpServiceMethod 的解析过程会创建这个适配器,前面说过它的创建是通过工厂模式的,所以要看下 RxJava2CallAdapterFactory 类的 get 方法,

@Override public @Nullable CallAdapter, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit){
    Class> rawType = getRawType(returnType);
    if (rawType == Completable.class) {
        return new RxJava2CallAdapter(Void.class, scheduler, isAsync, false, true, false, false, false, true);
    }
    boolean isFlowable = rawType == Flowable.class;
    boolean isSingle = rawType == Single.class;
    boolean isMaybe = rawType == Maybe.class;
    if (rawType != Observable.class && !isFlowable && !isSingle && !isMaybe) {
      return null;
    }

    boolean isResult = false;
    boolean isBody = false;
    Type responseType;
    Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
    Class> rawObservableType = getRawType(observableType);
    if (rawObservableType == Response.class) {
      responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
    } else if (rawObservableType == Result.class) {
      responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
      isResult = true;
    } else {
      responseType = observableType;
      isBody = true;
    }

    return new RxJava2CallAdapter(responseType, scheduler, isAsync, isResult, isBody, isFlowable, isSingle, isMaybe, false);
}

这里会涉及到一个 Java 反射接口 Type 以及 RxJava 里的几个类。

Type

这里的入参是在 HttpServiceMethod 解析时通过 Method 对象获取的返回类型,依照实际项目的写法,接口方法的返回应该是这样的,Observable ,再参考 Java反射——Type接口详解 和 Java反射中的Type类型 来理解,所以最终获取到的 rawType 应该是 Observable.class。

RxJava 定义的几个类

具体是指方法里涉及到的 Completable, Flowable, Single, Maybe。还是从 Observable 说起,通常接口方法的返回会用 Observable 来定义,Observable 将推送三种事件,onNext, onError, onCompleted。但倘若我们只关心一个结果,就可以把 Observable 用 Single 来代替。如果我们只关心完成与否,并不需要返回数据,可以把 Observable 用 Completable 来代替。如果需要有一个背压支持,就可以把 Observable 用 Flowable 来代替。Maybe 可以看成是 Single 和 Completable 的结合。以上只是参考了这两篇 理解RxJava中的Single和Completable,RxJava的Single、Completable以及Maybe 介绍个大概,具体还需要官网,或者实际使用。

有了一些概念后,再继续看方法,假设我们这个请求的 rawType 用的就是 Observable,那显然 isFlowable, isSingle, isMaybe 都是 false。

方法 getParameterUpperBound() 指的是获取泛型类参数的类型上限,拿方法的注释例子来说,

index 1 of {@code Map} returns {@code Runnable}.

所以代码里的意思是获取 Observable 中 T 的类型上限。根据实际项目使用情况 T 一般是个 JavaBean 类型,因此,isResult 为 false,isBody 为 true。

最后,根据这些参数值创建一个 RxJava2 适配器并返回。

分析了这几个变量来源含义,再回过头来看下 adapt 方法,

Observable> responseObservable = isAsync
    ? new CallEnqueueObservable(call)
    : new CallExecuteObservable(call);
//isAsync 由 RxJava2CallAdapterFactory 创建时确定,是 false
//所以会创建一个 CallExecuteObservable 对象
Observable> observable;
    if (isResult) {
      observable = new ResultObservable(responseObservable);
    } else if (isBody) {
      observable = new BodyObservable(responseObservable);
    } else {
      observable = responseObservable;
    }
//根据前面的分析 isBody 为 true
//observable 就是一个 BodyObservable 对象
return RxJavaPlugins.onAssembly(observable);
//最后只执行了这句并返回,但其实这里面没有做有效的操作,最终返回出来的就是 observable
//所以我们调用接口方法后返回的就是一个 BodyObservable 对象

Observable 在 Rx 概念里就代表着一个事件流,在订阅的时候就会触发操作,再往后就是利用 RxJava 的操作符以及订阅实现来完成网络请求了,这样一来也就完成了适配转换的过程。

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:qvyue@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。