创建完 OkHttpCall 对象后,以 RxJava2CallAdapter 为例,会调用 adapt 方法进行接下去的操作。这个方法的逻辑控制是通过一些变量值进行的,所以要先了解下各个变量值。
@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 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<JavaBean> ,再参考 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<String, ? extends Runnable>} returns {@code Runnable}.
所以代码里的意思是获取 Observable<T> 中 T 的类型上限。根据实际项目使用情况 T 一般是个 JavaBean 类型,因此,isResult 为 false,isBody 为 true。
最后,根据这些参数值创建一个 RxJava2 适配器并返回。
分析了这几个变量来源含义,再回过头来看下 adapt 方法,
Observable<Response<R>> 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 的操作符以及订阅实现来完成网络请求了,这样一来也就完成了适配转换的过程。
网友评论