Default Schedulers for rxjava on Android Default Schedulers for rxjava on Android multithreading multithreading

Default Schedulers for rxjava on Android


For Observable responses, Retrofit currently sets the subscribeOn as the HTTP executor of the RestAdapter (either provided or the default). This was done to shim RxJava support into the existing behavior.

The plan for 2.0 is to provide the ability to set defaults for both subscribeOn and observeOn explicitly (whether it be both, only one, or neither).

A reason you wouldn't want always want observation on the main thread is if you needed to chain multiple API calls together, for example.


The Change Log of Retrofit Version 2.0.0-beta2 (2015-09-28) shows subscribeOn() is required for running in the background.

Fix: Observable and Single-based execution of requests now behave synchronously (and thus requires subscribeOn() for running in the background).


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.