Is there RxJava equivalent of Handler.postDelayed(Runnable r, long delayMillis)

R. Zagórski picture R. Zagórski · Jun 30, 2016 · Viewed 7.3k times · Source

I am trying to invoke a method that returns void (Java primitive type). I would like to delay the invoking of a it by a predefined amount of milliseconds. I know this can be simply done using a Handler by I prefer not to use it.

I tried to do:

Observable.just(getView().setAttachments(attachments)).delay(50, TimeUnit.MILLISECONDS);

However, there is a compilation error, that:

Observable.just(java.lang.Void) cannot be applied to (void)

Is there another way? The reason I would like not to use a Handler is that the code is defined in Presenter (MVP pattern) and I would not like to use Android specific code in Java only class. I would prefer it to be a cold Observable, as I would not have to subscribe to it, just invoke the method only once.

Answer

MatBos picture MatBos · Jun 30, 2016

You can achieve this with defer, delay and doOnNext.

Observable.defer(() -> Observable.just(null)
            .delay(3, TimeUnit.SECONDS))
            .doOnNext(ignore -> LogUtils.d("You action goes here"))
            .subscribe();

In RxJava 2 you can use the following:

Completable.complete()
     .delay(3, TimeUnit.SECONDS)
     .doOnComplete(() -> System.out.println("Time to complete " + (System.currentTimeMillis() - start)))
     .subscribe();

Test code for Paul's version:

    @Test
public void testTimeToDoOnSubscribeExecution() {
    final long startTime = System.currentTimeMillis();
    System.out.println("Starting at: " + startTime);
    Subscription subscription = Observable.empty()
            .doOnSubscribe(() -> System.out.println("Time to invoke onSubscribe: " + (System.currentTimeMillis() - startTime)))
            .delay(1000, TimeUnit.MILLISECONDS)
            .subscribe();
    new TestSubscriber((rx.Observer) subscription).awaitTerminalEvent(2, TimeUnit.SECONDS);
}

Output:

Starting at: 1467280697232
Time to invoke onSubscribe: 122