之前的Retrofit学习(一)了解了一下Retrofit
的最基本使用,不过目前最流行的Retrofit
使用方式是Retrofit + RxJava + Gson
, 如果要使用RxJava
, 需要在创建Retrofit
时配置RxJava
对应的CallAdapter:
OkHttpclient client = new OkHttpClient.Builder().build();
Retrofit retrofit = new Retrofit.Builder()
.client(client)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.baseUrl("http://localhost:4567/")
.build();
下面就主要分析一下RxJava2CallAdapterFactory
是如何工作的
RxJava2CallAdapterFactory
public static RxJava2CallAdapterFactory create() {
return new RxJava2CallAdapterFactory(null, false);
}
public static RxJava2CallAdapterFactory createAsync() {
return new RxJava2CallAdapterFactory(null, true);
}
public static RxJava2CallAdapterFactory createWithScheduler(Scheduler scheduler) {
if (scheduler == null) throw new NullPointerException("scheduler == null");
return new RxJava2CallAdapterFactory(scheduler, false);
}
private final Scheduler scheduler;
private final boolean isAsync;
private RxJava2CallAdapterFactory(Scheduler scheduler, boolean isAsync) {
this.scheduler = scheduler;
this.isAsync = isAsync;
}
RxJava2CallAdapterFactory
提供了三个create
系列方法,一般情况下,最常使用的是第一个没有参数的create
方法,即不指定Scheduler
,isAsync = false
, isAsync
指明是调用Call.execute
还是Call.enqueue
RxJava2CallAdapterFactory.get
public 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;
//确保返回值是Observable, Flowable, Single, Maybe
if (rawType != Observable.class && !isFlowable && !isSingle && !isMaybe) {
return null;
}
boolean isResult = false;
boolean isBody = false;
Type responseType;
//ParameterizedType指泛型类型,如List<T>
if (!(returnType instanceof ParameterizedType)) {
String name = isFlowable ? "Flowable"
: isSingle ? "Single"
: isMaybe ? "Maybe" : "Observable";
throw new IllegalStateException(...);
}
//获取返回值的泛型参数
Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
Class<?> rawObservableType = getRawType(observableType);
if (rawObservableType == Response.class) {
//如果泛型参数是Response, 且Response没有泛型参数,抛出异常,Response必须是以泛型形式使用
if (!(observableType instanceof ParameterizedType)) {
throw new IllegalStateException(...);
}
//获取Response<T>中的T
responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
} else if (rawObservableType == Result.class) {
//如果泛型参数是Result, 且Result没有泛型参数, 抛出异常,Result必须是以泛型形式使用
if (!(observableType instanceof ParameterizedType)) {
throw new IllegalStateException(...);
}
//获取Result<T>中的T
responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
isResult = true;
} else {
responseType = observableType;
isBody = true;
}
return new RxJava2CallAdapter(responseType, scheduler, isAsync, isResult, isBody, isFlowable,
isSingle, isMaybe, false);
}``
- 如果返回值类型是
Completable
, 直接返回一个RxJava2CallAdapter
指定其中的isBody = true, isCompletable = true
- 确保方法的返回值
Observable
,Flowable
,Single
,Maybe
, 否则返回null, 如果是null, 则根据之前的分析,如果CallAdapter.Factory.get()
返回null, 在Retrofit.nextCallAdapter
中会抛出异常(Retrofit
默认有一个ExecutorCallAdapterFactory
, 但如果方法返回值不是Call
类型,其get()
方法会直接返回null) - 如果返回值不是泛型,抛出异常
- 获取返回值中的泛型参数的类型,假设返回值类型
Observable<Bean>
, 这里获取到的泛型参数类型就是Bean
- 如果泛型参数的类型是
retrofit2.Response
或retrofit2.Result
,确保Response
和Result
也是以泛型的形式声明的,即返回值类型是Observable<Response<T>>
或Observable<Result<T>>
;Retrofit + RxJava2
最常见的的用法是Observable<Bean> getName(...)
, 一般都会直接使用自定义的Bean
类, 所以一般情况下,isBody = true
- 返回
RxJava2CallAdapter
RxJava2CallAdapter.adapt
public Object adapt(Call<R> call) {
//call是OkHttpCall, 将R转换为Response<R>
Observable<Response<R>> responseObservable = isAsync
? new CallEnqueueObservable<>(call)
: new CallExecuteObservable<>(call);
Observable<?> observable;
if (isResult) {
observable = new ResultObservable<>(responseObservable);
} else if (isBody) {
//将Response<T>转换为T
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;
}
- 首先生成一个
Obsersavle<Response<R>>
, 这里会根据isAsync
是否为tru,来确定是生成CallEnqueueObservable
还是CallExecuteObservable
,这两者的区别在于前者最终实际是调用OkHttpCall.enqueue
方法,后者实际调用了OkHttpCall.execute
方法, 前者异步执行,后者同步执行 -
Retrofit + RxJava2
最常见的的用法是Observable<Bean> getName(...)
, 一般都会直接使用自定义的Bean
类, - 根据之前的分析可以知道,一般情况下,由于开发者都直接使用自己的Bean, 所以
isBody = true
, 会创建一个BodyObservable
- 之后会根据方法返回值是否是
Flowable, Single, Maybe, Completable
其中一种来做出具体的转换
BodyObservable
final class BodyObservable<T> extends Observable<T> {
private final Observable<Response<T>> upstream;
BodyObservable(Observable<Response<T>> upstream) {
this.upstream = upstream;
}
@Override
protected void subscribeActual(Observer<? super T> observer) {
//upstream是CallExecuteObservable或CallEnqueueObservable, BodyObserver是一个代理
//作用就是把Response<T>转换为T
upstream.subscribe(new BodyObserver<T>(observer));
}
private static class BodyObserver<R> implements Observer<Response<R>> {
private final Observer<? super R> observer;
private boolean terminated;
BodyObserver(Observer<? super R> observer) {
this.observer = observer;
}
@Override
public void onSubscribe(Disposable disposable) {
observer.onSubscribe(disposable);
}
@Override
public void onNext(Response<R> response) {
if (response.isSuccessful()) {
observer.onNext(response.body());
} else {
...
} }
}
@Override
public void onComplete() {
if (!terminated) {
observer.onComplete();
}
}
@Override
public void onError(Throwable throwable) {
if (!terminated) {
observer.onError(throwable);
} else {
...
}
}
}
}
这里upstream
是CallExecutorObservable
或CallEnqueueObservable
,一般情况下,这里会是CallExecutorObservable
;在subscribeActual
中可以看到,在传入的observer
外又包装了一个BodyObserver
, 传入的observer
就是开发者传入的自定义Observer
CallExecutorObservable
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) {
//originalCall是OkHttpCall
Call<T> call = originalCall.clone();
observer.onSubscribe(new CallDisposable(call));
boolean terminated = false;
try {
//call.execute会调用OkHttpCall.execute(), 从而得到okhttp3.Response
//再从okhttp3.Response中得到okhttp3.ResponseBody, 然后调用 Converter.convert转换结果,最后将接过封装为retrofit.Response
Response<T> response = call.execute();
if (!call.isCanceled()) {
//BodyObserver.onNext -> 自定义Onserver.onNext
observer.onNext(response);
}
if (!call.isCanceled()) {
terminated = true;
observer.onComplete();
}
} catch (Throwable t) {
...
}
}
private static final class CallDisposable implements Disposable {
private final Call<?> call;
CallDisposable(Call<?> call) {
this.call = call;
}
@Override
public void dispose() {
call.cancel();
}
@Override
public boolean isDisposed() {
return call.isCanceled();
}
}
}
originalCall
是OkHttpCall
, 可以看到在subscribeActual
中会调用call.execute
即调用OkHttpCall.execute
来从而得到okhttp3.Response, 再从okhttp3.Response中得到okhttp3.ResponseBody, 然后调用 Converter.convert
转换结果,最后将结果封装为retrofit.Response
,
subscribeActual
的参数observer
是BodyObserver
, 而从之前的分析中可以看到BodyObserver
的各方法会再调用开发人员自定义的Observer
的响应方法
这里看似比较抽象的一系列操作,是为了获得一个统一的结果, 一般开发人员在定义请求方法时,都会使用Observable<Bean>
这种方式,即直接将Observable<T>
中的T设为自定义Bean, 但不同场景下肯定会定义不同的类型Bean, Retrofit不可能预先知道开发人员会定义那些Bean, 为了得到一个统一的结果,先将Bean转换为Reponse<T>
,这样无论T是哪种类型,都可以得到一个统一的结果,之后再通过Response.body()
将Response转换为自定义Bean
网友评论