Frage Gibt es RxJava Entsprechung von Handler.postDelayed (Runnable r, long delayMillis)


Ich versuche, eine Methode aufzurufen, die void zurückgibt (primitiver Java-Typ). Ich möchte den Aufruf eines It um eine vordefinierte Anzahl von Millisekunden verzögern. Ich weiß, dass dies einfach mit a getan werden kann Handler indem ich es lieber nicht benutze.

Ich habe versucht zu tun:

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

Es gibt jedoch einen Kompilierungsfehler, der:

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

Gibt es eine andere Art und Weise? Der Grund, warum ich nicht a Handler ist, dass der Code in Presenter (MVP-Muster) definiert ist und ich nicht möchten, Android-spezifischen Code in nur Java-Klasse zu verwenden. Ich würde es vorziehen, ein kaltes Observable zu sein, da ich es nicht abonnieren müsste, rufen Sie die Methode nur einmal auf.


6
2018-06-30 09:02


Ursprung


Antworten:


Sie können dies mit erreichen verschieben, verzögern und doOnNext.

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

In RxJava 2 können Sie Folgendes verwenden:

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

Testcode für Pauls 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);
}

Ausgabe:

Starting at: 1467280697232
Time to invoke onSubscribe: 122

20
2018-06-30 09:48



Verwenden Sie einfach

subscription = Observable.timer(1000, TimeUnit.MILLISECONDS)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(aLong -> whatToDo());

private void whatToDo() {
   System.out.println("Called after 1 second");
}

2
2018-02-24 03:48



Wenn Sie nichts in Ihrer Pipeline ausgeben wollen, sehe ich nicht den Punkt, eine Pipeline zu verwenden, nur um die Verzögerung zu verwenden ?.

Wie auch immer, was Sie erreichen wollen, hat keinen Sinn, Sie können kein Observable erstellen, das nichts ausstrahlt.

Aber wenn Sie es trotzdem verwenden möchten, können Sie immer einen Operator wie doOnSubscribe verwenden

     @Test
   public void observableDoOnSubscribe() {
    Observable.empty()
              .delay(50, TimeUnit.MILLISECONDS
              .doOnSubscribe(() -> getView().setAttachments(attachments))
              .subscribe();
}

Um zu testen, dass die Verzögerung funktioniert

        boolean onSubscribe = false;

@Test
public void observableDoOnSubscribe() {
    Subscription subscription = Observable.just(System.currentTimeMillis())
              .doOnSubscribe(() -> onSubscribe = true)
              .delay(1000, TimeUnit.MILLISECONDS)
              .filter(s -> onSubscribe)
              .subscribe(t-> System.out.println("Pipeline spend time:" + (System.currentTimeMillis()-t)));

    new TestSubscriber((Observer) subscription)
            .awaitTerminalEvent(2, TimeUnit.SECONDS);
}

Mehr reaktive Beispiele hier https://github.com/politrons/reactive


1
2018-06-30 09:10



Wenn dein Thread dann zu Ui gehört

Completable.complete()
            .delay(100, TimeUnit.MILLISECONDS).observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.io())
            .doOnComplete(() -> tabLayout.getTabAt(selectableTab).select())
            .subscribe();

-1
2018-03-23 14:14