2016-06-30 12 views
4

Ich versuche, eine Methode aufzurufen, die void (primitiven Typ Java) zurückgibt. Ich möchte den Aufruf eines It um eine vordefinierte Anzahl von Millisekunden verzögern. Ich weiß, dass dies einfach mit einem Handler getan werden kann, ich bevorzuge es nicht zu verwenden.Gibt es ein RxJava-Äquivalent von Handler.postDelayed (Runnable r, long delayMillis)

Ich habe versucht zu tun:

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

Allerdings gibt es einen Übersetzungsfehler, dass:

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

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

Antwort

17

können Sie erreichen Sie dies mit defer, delay und doOnNext.

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

In RxJava 2 Sie Folgendes verwenden:

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

Prüfregeln für Paul-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); 
} 

Ausgang:

Starting at: 1467280697232 
Time to invoke onSubscribe: 122 
+0

Überprüft diese Antwort und die andere. Dieser funktioniert mit jeder Verzögerung. Vielen Dank. –

+0

Was ist mit Speicherleck? –

+0

Können Sie es ausarbeiten? – MatBos

1

Wenn Sie nichts in Ihrer Pipeline ausstrahlen 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 verwenden möchten trotzdem kann man immer einen Operator wie doOnSubscribe verwenden

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

diese Verzögerung Um zu testen, 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); 
} 

Reaktivere Beispiele hier https://github.com/politrons/reactive

+0

ich dachte, dass es eine andere Art und Weise ist, aber das funktioniert auch. Vielen Dank. –

+0

Dieser Code verzögert die Ausführung von nichts. Wie der Name der Methode angibt ('doOnSubscribe'), wird die Ausführung beim Abonnement ausgeführt. Versuchen Sie es mit einer größeren Verzögerung und testen Sie es dann. – MatBos

+0

@MatBos Warum hast du gesagt, die Verzögerung wird nicht auf die DoOnSubscribe angewendet ?, Ich denke, du bist falsch, aber könnten Sie bitte kopieren und führen Sie das zweite Beispiel, das ich einfügen?. Es funktionierte für mich, verzögerte die Pipeline 1 Sekunde + die Pipeline verbringen Zeit. – paul

1

Verwenden 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"); 
}