Robert Lewis
Robert Lewis

Reputation: 1907

Rx Subject can't use observeOn() operator

I've declared:

Subject<String> mBehaviorSubject = BehaviorSubject.createDefault("default").toSerialized();

Seems to work fine. But I now want to add .observeOn(AndroidSchedulers.mainThread(). This is rejected because Android Studio wants to see a Subject and is finding an Observable. But according to the documentation, Subject inherits the observeOn() method from the Observable class. How do I make this work?

P.S. Assuming I can do this, is there any preferred order of the operators observeOn() and toSerialized()?

Update: here is the actual complete code I'm trying to use:

Subject<String> stringPublisher; 
...
stringPublisher = BehaviorSubject.createDefault("default").toSerialized().observeOn(AndroidSchedulers.mainThread());

Android Studio says "incompatible types: required: io.reactivex.subjects.Subject; found: io.reactivex.Observable"

Upvotes: 1

Views: 181

Answers (1)

Ben P.
Ben P.

Reputation: 54194

This is rejected because Android Studio wants to see a Subject and is finding an Observable. But according to the documentation, Subject inherits the observeOn() method from the Observable class.

You are correct that Subject inherits this method, but that doesn't change the return type of the observeOn method; it still returns an Observable<T>. Because you're trying to do assignment, this will break.

Let's go through each call...

Subject<String> subject = BehaviorSubject.createDefault("default");

This is fine; createDefault() returns a BehaviorSubject<T>, which is a subclass of Subject<T>, so there's no problem assigning its value to our subject variable.

Subject<String> subject = BehaviorSubject.createDefault("default").toSerialized();

This is also fine; toSerialized() returns a Subject<T>, so our assignment still works. Note, though, that this is still "less specific" than BehaviorSubject<T>, so if our variable declaration were instead BehaviorSubject<String> subject, this would already break.

Subject<String> subject = BehaviorSubject.createDefault("default")
                                         .toSerialized()
                                         .observeOn(AndroidSchedulers.mainThread());

Here we finally break. observeOn() returns an Observable<T>, and while a Subject "is an" Observable, we still cannot make the assignment anymore because we have an object of the wrong type. This is similar to trying to assign an Object to a String variable.

So, you either have to change your declaration to Observable<String> subject (so that you can perform the assignment), or you have to break your code up into an assignment and a statement:

Subject<String> subject = BehaviorSubject.createDefault("default").toSerialized();
Observable<String> observable = subject.observeOn(AndroidSchedulers.mainThread());

Upvotes: 2

Related Questions