Yes, it's possible to remove both calls.
Here is the retrofit adapter class that automatically schedules both subscribeOn
and observedOn
to remove the need for the boilerplate calls in each invocation:
public class RxThreadingCallAdapterFactory extends CallAdapter.Factory {
private final RxJava2CallAdapterFactory original;
private RxThreadingCallAdapterFactory() {
// Always call on background thread
original = RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io());
}
public static CallAdapter.Factory create() {
return new RxThreadingCallAdapterFactory();
}
@Override
public CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
return new RxCallAdapterWrapper(original.get(returnType, annotations, retrofit));
}
private static class RxCallAdapterWrapper implements CallAdapter<Observable<?>> {
private final CallAdapter<?> wrapped;
public RxCallAdapterWrapper(CallAdapter<?> wrapped) {
this.wrapped = wrapped;
}
@Override
public Type responseType() {
return wrapped.responseType();
}
@Override
public <R> Observable<?> adapt(Call<R> call) {
Observable observable = (Observable) wrapped.adapt(call);
// Always handle result on main thread
return observable.observeOn(AndroidSchedulers.mainThread());
}
}
}
Then use this adapter when configuring retrofit:
Retrofit.Builder()
.baseUrl(...)
.addCallAdapterFactory(RxThreadingCallAdapterFactory.create())
I wrote this blog post that goes into a lot of detail on exactly what's happening here.
This will remove both calls, which I consider boilerplate. I consider Jake's scenario of chaining together background calls to not really apply, because in this case I would do retrofit synchronous calls and not use schedulers at all.