15

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?

Jacek Laskowski
  • 72,696
  • 27
  • 242
  • 420
wttek
  • 173
  • 1
  • 7

1 Answers1

40

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

dwursteisen
  • 11,435
  • 2
  • 39
  • 36
  • 6
    You can also: `Observable.defer(() -> Observable.just(getMessagesFromDb()).subscribeOn(Schedulers.newThread()))` – Ross Hambrick Mar 23 '15 at 20:31
  • 1
    A detailed and thorough explanation that helped more than just for this one example. – miroslavign Jun 02 '16 at 12:51
  • 1
    This example indeed explained really well the concept and usage case of defer and just operator. Thanks for much for this. – toantran Jun 29 '16 at 09:50
  • How you would do this in RxJava2? Calling defer or fromCallable won't execute unless you call subscribe on it effectively converting the type to a Disposable. What if i want to have a Observable/Flowable. – Marcin D Feb 07 '18 at 15:33