之前面试有问到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进行线程切换。