in 0.18, how do background tasks get executed on a scheduler?

rx-java

Solution

Using Scheduler with Observable

If you are using RxJava, I think you should let Observables deal with the Schedulers. In my code I don't think I ever had to create my own worker and mange it.

Example of using Observable with Scheduler and switching between two thread types.

public void doSomething() {
    Observable
            .create(new Observable.OnSubscribe<Boolean>() {
                @Override
                public void call(Subscriber<? super Void> subscriber) {
                    int sleepTime = (int) (Math.random() * 10000);

                    System.out.println("Running on: " + Thread.currentThread().getId() + " sleep: " + sleepTime);

                    try {
                        Thread.sleep(sleepTime);
                    } catch (InterruptedException e) {
                        System.out.println("Error!!! " + Thread.currentThread().getId());
                        subscriber.onError(e);
                        return;
                    }

                    System.out.println("Done!!! " + Thread.currentThread().getId());
                    subscriber.onNext(true);
                    subscriber.onCompleted();
                }
            })
            // this will schedule your work in a background io thread. In this example the "call" method above.
            .subscribeOn(Schedulers.io())
            // this will schedule your next/complete/error on the androids main thread.
            .observeOn(AndroidSchedulers.mainThread())
            // kick off the actual work.
            .subscribe(new Subscriber<Boolean>() {
                @Override
                public void onCompleted() {
                    // runs in main thread.
                }

                @Override
                public void onError(Throwable e) {
                    // runs in main thread.
                }

                @Override
                public void onNext(Boolean result) {
                    // runs in main thread.
                }
            });
}

Using Scheduler Directly

However, I do understand that there might be a case requiring you to use the scheduler directly. So, if you want to use the Scheduler directly. I think the following fits what you are looking for.

Create a scheduler utility with a runAction.

public static void runAction(Action0 action, Scheduler scheduler) {
    Scheduler.Worker worker = scheduler.createWorker();
    worker.schedule(new Action0() {
        @Override
        public void call() {
            action.call();
            worker.unsubscribe();
        }
    });
}

Then to use it, pass an action to execute and the scheduler to use.

SchedulerUtil.runAction(new Action0() {
    @Override
    public void call() {
        int sleepTime = (int) (Math.random() * 10000);

        System.out.println("Running on: " + Thread.currentThread().getId() + " sleep: " + sleepTime);
        try {
            Thread.sleep(sleepTime);
        } catch (InterruptedException ignored) {
        }

        System.out.println("Done!!! " + Thread.currentThread().getId());
    }
}, Schedulers.io());

Problem

Feels like I'm missing something here, but where I used to do: ``` Schedulers.io().schedule(new Action1<Scheduler.Inner>() { @Override public void call(Scheduler.Inner inner) { doWhatever(); } }); ``` I don't seem to be able to simply use a scheduler to run a background task anymore, without managing unsubscribes (https://github.com/Netflix/RxJava/wiki/Scheduler and https://github.com/Netflix/RxJava/blob/master/rxjava-core/src/main/java/rx/Scheduler.java). Is there a pattern for 0.18 that allows me to run doWhatever easily, without keeping track of workers, unsubscribing, etc? Seems like you could do: ``` final Worker worker = Schedulers.io().createWorker(); worker.schedule(new Action0() { @Override public void call() { doWhatever(); worker.unsubscribe(); } }); ``` but this seems like a lot more work, (especially for the android.mainThread scheduler). What have I missed here?

Original source