tse
tse

Reputation: 6079

How to override Schedulers.io()?

I need to emulate app's behavior on very slow devices. So I want to override Schedulers.io() to use only one thread with low priority. And, if it possible, to add some delay before putting task to queue. Is there any ideas how to do it once globally, without change Schedules.io() call in code?

Upvotes: 0

Views: 353

Answers (1)

akarnokd
akarnokd

Reputation: 69997

You can wrap a single threaded executor via Schedulers.from(Executor) then wrap the resulting Scheduler with another:

ExecutorService exec = Executors.newSingleThreadExecutor();
final Scheduler sch = Schedulers.from(exec);
final long delayMillis = 1000;

Scheduler newScheduler = new Scheduler() {
    @Override public Worker createWorker() {
        return new NewWorker(sch.createWorker());
    }

    class NewWorker extends Scheduler.Worker {
        final Worker actual;

        NewWorker(Worker actual) {
            this.actual = actual;
        }

        @Override public void unsubscribe() {
            actual.unsubscribe();
        }

        @Override public boolean isUnsubscribed() {
           return actual.isUnsubscribed();
        }

        @Override public Subscription schedule(Action0 action) {
            return actual.schedule(action, delayMillis, TimeUnit.MILLISECONDS);
        }

        @Override public Subscription schedule(Action0 action, long delayTime,
               TimeUnit unit) {
            return actual.schedule(action, delayTime, unit);
        }
    }
};

RxJavaHooks.setOnIOScheduler(original -> newScheduler);

Observable.just(1)
.observeOn(Schedulers.io())
.toBlocking()
.subscribe(System.out::println);

Don't forget to shut down the ExecutorService and reset the hook once you are done:

exec.shutdown();
RxJavaHooks.setOnIOScheduler(null);

Upvotes: 1

Related Questions