Amjad Omari
Amjad Omari

Reputation: 1112

How can I change the period for Observable.interval, and how can I stop and resume the Observable ticks at runtime

is there a way to change the Observable.interval period at runtime? and is there a way to stop and resume the Observable.interval ticks? and is there a way to reset the interval period?

actually I'm using the following code to do an action for ever in a period time, but I have no control on it during the run time, I have to stop, resume, rest, and change the period at runtime.

Observable.interval(8, TimeUnit.SECONDS).observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<Long>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                            Log.i("TAG", "onSubscribe");
                        }

                        @Override
                        public void onNext(Long aLong) {
                            myMethod();
                        }

                        @Override
                        public void onError(Throwable e) {
                            Log.i("TAG", "onError");
                        }

                        @Override
                        public void onComplete() {
                            Log.i("TAG", "onComplete");
                        }
                    });

I have tried to google it to find a solution, but unfortunately I did not find any one, and I need a help or a resource if there is any.

Upvotes: 0

Views: 1600

Answers (3)

Amjad Omari
Amjad Omari

Reputation: 1112

Here it is my solution to handle the issue

private PublishSubject<Long> newInterval;

// reactive programming using RXJava2
private void prepareObserver() {
    newInterval = PublishSubject.create();

    newInterval.switchMap(currentPeriod ->
            Observable.interval(currentPeriod, TimeUnit.MILLISECONDS).subscribeOn(Schedulers.single())
    )
            .doOnNext(v -> runOnUiThread(this::pagerForeword))
            .subscribe();

    newInterval.onNext(period);
}

and to reset the interval period I call

newInterval.onNext(period);

and you can find the full solution over the following resource tutorial here

I hope this be useful!

Upvotes: 2

akarnokd
akarnokd

Reputation: 69997

As @DDH indicated, perhaps the simplest way is to cancel an ongoing interval and start a new flow completely.

However, if you have to maintain the chain below the interval for some reason, you can switch to a new interval via the switchMap operator, triggered by a PublishSubject for example:

PublishSubject<Long> newInterval = PublishSubject.create();

newInterval.switchMap(currentPeriod ->
    Observable.interval(currentPeriod, TimeUnit.MILLISECONDS)
)
.doOnNext(v -> { /* background work */ })
.observeOn(AndroidSchedulers.mainThread())
.subscribe(/* ... */);

newInterval.onNext(1000L);

// sometime later

newInterval.onNext(200L);

Upvotes: 8

DDH
DDH

Reputation: 29

I'm not 100% sure what did you mean by " I have to stop, resume, rest, and change the period at runtime." But you can dispose subscription and reinit observable with new period on runtime:

    Disposable d = Observable.interval(1, TimeUnit.SECONDS)
            .subscribeOn(Schedulers.single())
            .subscribe(new Consumer<Long>() {
                @Override
                public void accept(Long aLong) throws Exception {

                }
            });
    d.dispose();    

Upvotes: 0

Related Questions