J'essaie de remplacer ma méthode Handler par Rx Java . Mon exigence
Je veux appeler la méthode getTransactionDetails () seulement après 5 secondes.
cela mon code de travail en utilisant Handler
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
getTransactionDetails();
}
}, 5000);
Code Java Rx - ça ne marche pas
Observable.empty().delay(5000, TimeUnit.MILLISECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnNext(o -> getTransactionDetails())
.subscribe();
doOnNext()
est destiné aux effets secondaires. Cela pourrait être utilisé par exemple à des fins de journalisation, car la journalisation ne modifie pas le flux de données. Mais vous voulez transmettre le résultat de getTransactionDetails()
, vous devriez donc utiliser map à la place.
Deuxièmement, Observable.empty()
create a Observable
qui ne fait que propager le message de fin/disposition, il ne déclenche ni doOnNext()
, ni map()
. Vous pouvez résoudre ce problème en utilisant Observable.just()
à la place, mais une méthode plus idiomatique consisterait à utiliser Observable.timer()
:
Observable.timer(5000, TimeUnit.MILLISECONDS)
.map(o -> getTransactionDetails())
.observeOn(AndroidSchedulers.mainThread())
.subscribe( ... );
Une note finale sur les planificateurs. Observable.timer()
et delay()
sont exécutés par défaut sur le planificateur de calcul, vous n'avez donc pas besoin d'appeler .subscribeOn(Schedulers.io())
pour exécuter getTransactionDetails()
en dehors du thread principal. Observable.timer()
et delay()
peuvent prendre une Scheduler
en tant que paramètre si vous souhaitez contrôler cela. Vous devez donc appeler .observeOn(AndroidSchedulers.mainThread())
si vous voulez utiliser le résultat getTransactionDetails()
sur le thread d'interface utilisateur. Chaque opérateur après observeOn()
est exécuté sur la Scheduler
définie, vous devez donc mettre observeOn()
après le calcul.
Edit: Ceci est bien sûr si vous vous souciez du résultat de getTransactionDetails()
. Sinon, voir la réponse de Clyde.
Voici comment je le ferais:
Completable.timer(5, TimeUnit.SECONDS, AndroidSchedulers.mainThread())
.subscribe(this::getTransactionDetails);
A Completable représente un calcul différé sans valeur mais une indication de fin ou d'exception. L'appel à la méthode statique timer()
renvoie une Completable
qui signale l'achèvement de la période spécifiée et l'appel subscribe()
signifie que la méthode getTransactionDetails()
sera appelée sur l'objet actuel lors du déclenchement de la minuterie. En fournissant une Scheduler
comme dernier argument de Completable.timer()
, vous contrôlez le thread utilisé pour exécuter getTransactionDetails()
.
Observable
.timer( 5000, TimeUnit.MILLISECONDS )
.subscribeOn(Schedulers.io())
.map(o -> getTransactionDetails() )
.subscribe();
vous n’avez pas besoin d’observer parce que vous êtes abonné vide .
Cela ne fonctionne pas, parce que delay()
a besoin d'émettre quelque chose, mais empty()
n'émet en réalité rien.
Au lieu de cela, vous devriez utiliser Observable.timer()
.
Essaye ça
Observable.just(true).delay(5000, TimeUnit.MILLISECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.map(o -> getTransactionDetails())
.subscribe();
Si vous voulez un objet jetable utilisable avec la vue, utilisez un objet Completable Completable renvoie un objet qui se termine dès que l’un des éléments source Completables se termine (normalement ou avec une erreur) et annule tous les autres objets Completables.
Par exemple :
Completable.timer(5, TimeUnit.SECONDS, AndroidSchedulers.mainThread())
.subscribe(() -> {
// code after delay here
});
Si vous souhaitez qu'un service soit complet, je vous recommanderais un abonnement.
Par exemple :
observable.timer(5000, TimeUnit.MILLISECONDS)
.map(o -> {
// your code after delay here
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe( ()-<{
// enter the service here
} );