RxJava single background thread scheduler

casolorz picture casolorz · Apr 17, 2015 · Viewed 15.5k times · Source

I'm fairly new to RxJava so this is probably a dumb question. I am going to describe my scenario.

I have some code running on the UI thread which will update some images but those images are not very important and they consume a bit of resources while generating them so I want to generate them on a single thread (not the UI thread of course) and generate them one by one. I'm guessing the trampoline scheduler is what I want but my problem is that if I use it then it does the work on the UI thread and I want it to do it on another thread.

Obviously I can write my own thread in which I can queue items and then it processes those one by one but I thought maybe RxJava would have a simple solution for me?

My current code looks like this:

Observable<Bitmap> getImage = Observable.create(new Observable.OnSubscribe<Bitmap>() {
    @Override public void call(Subscriber<? super Bitmap> subscriber) {
        Log.w(TAG,"On ui thread? "+ UIUtils.isRunningOnUIThread());
        subscriber.onNext(doComplexTaskToGetImage());
        subscriber.onCompleted();
    }
});

getImage.subscribeOn(Schedulers.trampoline()).subscribe(new Action1<Bitmap>() {
    @Override public void call(Bitmap bitmap) {
        codeToSetTheBitmap(bitmap);
    }
});

My log that says "On ui thread?" always has true. So how do I make that code and all subsequent attempts to do the same thing run on a single thread (not the ui thread) in order without writing a bunch of code to queue that work?

Edit:

I believe that this can now be accomplished using Schedulers.single() or if you want your own you can use new SingleScheduler(). I'm still testing but I think it does what I wanted back when I posted this.

Answer

corsair992 picture corsair992 · Apr 18, 2015

You can create a single reusable thread to create a Scheduler for the Observable in one of the following ways:

  • Create a ThreadPoolExecuter with a pool size of 1 (Executors.newSingleThreadExecutor() is a convenient static factory method for doing that), then use it to generate the schedulers via the Schedulers.from() method.
  • RxAndroid provides a custom Scheduler implementation that uses a Handler to schedule the actions, and thus can be used with any Thread that has a Looper running by passing it's Handler to the AndroidSchedulers.handlerThread() factory method.

Note that you will need to observe on a main thread Scheduler if you're interacting with the UI at the conclusion of these tasks.