Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RxJava - How to stop (and resume) a Hot Observable (interval)?

I have the following Hot Observable:

hotObservable = Observable.interval(0L, 1L, TimeUnit.SECONDS)
                          .map((t) -> getCurrentTimeInMillis()))

However, I can't find a good way to stop it. I was able to partially solve this using takeWhile and a boolean flag (runTimer):

Observable.interval(0L, 1L, TimeUnit.SECONDS)
          .takeWhile((t) -> runTimer)
          .map((t) -> getCurrentTimeInMillis()))

There are 2 things I don't like in this approach though:

  1. I must keep the flag runTimer around, which I don't want.
  2. Once runTimer becomes false, the Observable simply completes, which means if I want to emit again I need to create a new Observable. I don't want that. I just want the Observable stop emitting items until I tell it to start again.

I was hoping for something like this:

hotObservable.stop();
hotObservable.resume();

That way I don't need to keep any flags around and the observable is always alive (it might not be emitting events though).

How can I achieve this?

like image 580
Bitcoin Cash - ADA enthusiast Avatar asked Dec 09 '16 23:12

Bitcoin Cash - ADA enthusiast


1 Answers

One possible approach uses a BehaviorSubject and a switchMap:

BehaviorSubject<Boolean> subject = BehaviorSubject.create(true);
hotObservable = subject.distinctUntilChanged().switchMap((on) -> {
    if (on) {
        return Observable.interval(0L, 1L, TimeUnit.SECONDS);
    } else {
        return Observable.never();
    }
}).map((t) -> getCurrentTimeInMillis());

By sending booleans to the subject the output of the observable can be controlled. subject.onNext(true) will cause any observable created using that subject to begin emitting values. subject.onNext(false) disables that flow.

The switchMap takes care of disposing the underlying observables when it is switched off. It also uses distinctUntilChanged to make sure it does not do unnecessary switching.

like image 56
Kiskae Avatar answered Sep 22 '22 16:09

Kiskae