Reputation: 664
I am building an Android MVVM application using RxJava2. What I want is to expose an Observable
in my ViewModel, which I also can receive the last emitted value (like a BehaviourSubject
). I don't want to expose a BehaviourSubject
because I don't want the View to be able to call onNext()
.
For example, in my ViewModel
I expose a date. I now want to subscribe a TextView
to changes, but I also need to be able to access the current value if I want to show a DatePickerDialog
with this date as initial value.
What would be the best way to achieve this?
Upvotes: 4
Views: 3034
Reputation: 70007
Delegate:
class TimeSource {
final BehaviorSubject<Long> lastTime = BehaviorSubject.createDefault(
System.currentTimeMillis());
public Observable<Long> timeAsObservable() {
return lastTime;
}
public Long getLastTime() {
return lastTime.getValue();
}
/** internal only */
void updateTime(Long newTime) {
lastTime.onNext(newTime);
}
}
Upvotes: 3
Reputation: 62209
I don't want to expose a
BehaviourSubject
Subject
, by definition, is "an Observer
and an Observable
at the same time". Therefore, instead of exposing BehaviorSubject
itself just expose Observable
, thus client (in this case the view) won't be able to perform onNext()
, but will be able to receive last emitted value.
As an alternative to subject approach you can use replay(1).autoConnect()
approach. See more details concerning this approach in "RxJava by example" presentation by Kaushik Gopal.
Also, consider cache()
operator (see difference of cache
and replay().autoConnect()
here).
Upvotes: 2