Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stop and resume Observable.interval emiting ticks

This will emit a tick every 5 seconds.

Observable.interval(5, TimeUnit.SECONDS, Schedulers.io())             .subscribe(tick -> Log.d(TAG, "tick = "+tick)); 

To stop it you can use

Schedulers.shutdown(); 

But then all the Schedulers stops and it is not possible to resume the ticking later. How can I stop and resume the emiting "gracefully"?

like image 558
Jan Seevers Avatar asked Feb 15 '16 21:02

Jan Seevers


People also ask

How do you stop observable from emitting?

Use RxJS first operator The observable$ will complete if the interval emits its first value. That means, in our console, we will see only 1 log and nothing else. At point will stop emitting values. Here, first will not emit a value until interval emits a value that is equal to 10, then it will complete the observable$.

What is observable interval?

Interval Method (TimeSpan) Returns an observable sequence that produces a value after each period.


2 Answers

Here's one possible solution:

class TickHandler {      private AtomicLong lastTick = new AtomicLong(0L);     private Subscription subscription;      void resume() {         System.out.println("resumed");         subscription = Observable.interval(5, TimeUnit.SECONDS, Schedulers.io())                                  .map(tick -> lastTick.getAndIncrement())                                  .subscribe(tick -> System.out.println("tick = " + tick));     }      void stop() {         if (subscription != null && !subscription.isUnsubscribed()) {             System.out.println("stopped");             subscription.unsubscribe();         }     } } 
like image 110
AndroidEx Avatar answered Sep 17 '22 20:09

AndroidEx


Some time ago, I was also looking for kind of RX "timer" solutions, but non of them met my expectations. So there you can find my own solution:

AtomicLong elapsedTime = new AtomicLong(); AtomicBoolean resumed = new AtomicBoolean(); AtomicBoolean stopped = new AtomicBoolean();  public Flowable<Long> startTimer() { //Create and starts timper     resumed.set(true);     stopped.set(false);     return Flowable.interval(1, TimeUnit.SECONDS)             .takeWhile(tick -> !stopped.get())             .filter(tick -> resumed.get())             .map(tick -> elapsedTime.addAndGet(1000)); }  public void pauseTimer() {     resumed.set(false); }  public void resumeTimer() {     resumed.set(true); }  public void stopTimer() {     stopped.set(true); }  public void addToTimer(int seconds) {     elapsedTime.addAndGet(seconds * 1000); } 
like image 24
Artur Szymański Avatar answered Sep 17 '22 20:09

Artur Szymański