37

So I am trying to create an observable which fires on a regular basis, but for some reason which I cannot figure out, it only fires once. Can anyone see what I am doing wrong?

Observable<Long> observable = Observable.timer(delay, TimeUnit.SECONDS, Schedulers.io());

        subscription =  observable
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<Long>() {
                    @Override
                    public void call(Long aLong) {
                        searchByStockHelper.requestRemoteSearchByStock();
                    }
                });

currently delay is set to 2

James King
  • 2,425
  • 7
  • 30
  • 45

3 Answers3

59

The documentation for the timer operator says this:

Create an Observable that emits a particular item after a given delay

Thus the behavior you are observing is expected- timer() emits just a single item after a delay.

The interval operator, on the other hand, will emit items spaced out with a given interval.

For example, this Observable will emit an item every second:

Observable.interval(1, TimeUnit.SECONDS);
Bryan Herbst
  • 66,602
  • 10
  • 133
  • 120
  • This is great except how do i prevent it from memory leaking. – ldrrp Oct 15 '19 at 13:37
  • @ldrrp what makes you think this leaks anything – Tim Nov 19 '19 at 12:22
  • Theres a very small leak that i managed to graph numerous times without failure on separate android versions/emulators/devices. I moved on to something else after the devs on github refused to ack the issue. – ldrrp Jan 08 '20 at 21:31
21

I know topic is old but maybe for future visitors. (5 min count down timer)

Disposable timerDisposable = Observable.interval(1,TimeUnit.SECONDS, Schedulers.io())
        .take(300)
        .map(v -> 300 - v)
        .subscribe(
            onNext -> {
                //on every second pass trigger
            },
            onError -> {
                //do on error
            },
            () -> {
                //do on complete
            },
            onSubscribe -> {
                //do once on subscription
            });
Jakub S.
  • 5,580
  • 2
  • 42
  • 37
1

I implemented like this in my code as it make sure task running is finished before invoking again, and you can update delay.

 return Single.timer(5, TimeUnit.SECONDS).flatMap(
        new Function<Long, Single<Object>>() {
          @Override
          public Single<Object> apply(Long aLong) {
            //create single with task to be called repeatedly
            return Single.create();
          }
        })
        .retry(new Predicate<Throwable>() {
          @Override
          public boolean test(Throwable throwable) {
            boolean response = true;
            //implement your logic here and update response to false to stop 
              retry
            return response;
          }
        });
1'hafs
  • 559
  • 7
  • 25