Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does subscribe not executed in a new thread?

I have task like this:

Observable.just(getMessagesFromDb()).
    subscribeOn(Schedulers.newThread()).
    observeOn(AndroidSchedulers.mainThread()).
    subscribe(incomingMessages -> {
    //do something
    });

where getMessagesFromDb is method synchronously getting messages, without multithreading inside. According to the RxAndroid documentation for subscribeOn method:

Asynchronously subscribes Observers to this Observable on the specified Scheduler

And there is my question - why is the database request executed on main thread? How to do it asynchronously?

like image 410
wttek Avatar asked Mar 20 '15 14:03

wttek


1 Answers

What you see below is a slightly modified version of your code with getMessagesFromDb() called to assign a return value to a variable:

 Object data = getMessagesFromDb();
 Observable.just(data).
    subscribeOn(Schedulers.newThread()).
    observeOn(AndroidSchedulers.mainThread()).
    subscribe(incomingMessages -> {
      //do something
    });

It's exactly how Observable.just works, and getMessagesFromDb() is indeed called in the main thread (as you're calling it in the main thread).

You have to defer it using Observable.fromCallable method as follows:

Observable.fromCallable(() -> getMessageFromDb()).
           subscribeOn(Schedulers.newThread()).
           observeOn(AndroidSchedulers.mainThread()).
           subscribe(incomingMessages -> {
              //do something
           });

Please note that you can use Observable.defer instead of Observable.fromCallable, but it's a little bit more complicated :

Observable.defer(() -> Observable.just(getMessageFromDb()))

The previous version of this response use Observable.create. But it is complicated to build an Observable with this method. Try to always prefer Observable.defer or Observable.fromCallable

like image 184
dwursteisen Avatar answered Nov 08 '22 10:11

dwursteisen