J'utilise RxAndroid pour les opérations de flux. Dans mon cas d'utilisation réel, je récupère une liste du serveur (en utilisant Retrofit). J'utilise des planificateurs pour effectuer le travail sur un thread d'arrière-plan et obtenir l'émission finale sur le thread Android UI (main)).
Cela fonctionne bien pour l'appel réseau, mais j'ai réalisé que mes opérateurs après l'appel réseau n'utilisent pas le thread d'arrière-plan, mais sont appelés sur le thread principal.
myService.fetchSomeIntegersFromServer()
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.filter(integer -> {
System.out.println(Looper.getMainLooper().getThread() == Thread.currentThread());
return true;
})
.subscribe(integer1 -> {});
Comment puis-je m'assurer que toutes les opérations sont exécutées sur un thread d'arrière-plan?
TL; DR : déplacez observeOn(AndroidSchedulers.mainThread())
sous filter(...)
.
subscribeOn(...)
est utilisé pour désigner sur quel thread le Observable
va commencer fonctionner. Les appels suivants à subscribeOn
seront ignorés.
Ainsi, si vous deviez écrire ce qui suit, tout serait exécuté sur Schedulers.newThread()
:
myService.fetchSomeIntegersFromServer()
.subscribeOn(Schedulers.newThread())
.filter(integer -> {
System.out.println(Looper.getMainLooper().getThread() == Thread.currentThread());
return true;
})
.subscribe(integer1 -> { doSomething(integer1); });
Maintenant, bien sûr, ce n'est pas ce que vous voulez: vous voulez doSomething
sur le thread principal.
C'est là que observeOn
se met en place. Toutes les actions aprèsobserveOn
sont exécutées sur ce planificateur. Par conséquent, dans votre exemple, le filter
est exécuté sur le thread principal.
Au lieu de cela, déplacez observeOn
vers le bas juste avant subscribe
:
myService.fetchSomeIntegersFromServer()
.subscribeOn(Schedulers.newThread())
.filter(integer -> {
System.out.println(Looper.getMainLooper().getThread() == Thread.currentThread());
return true;
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(integer1 -> { doSomething(integer1) });
Maintenant, filter
se produira sur le 'nouveau thread', et doSomething
sur le thread principal.
Pour aller encore plus loin, vous pouvez utiliser observeOn
plusieurs fois:
myService.fetchSomeIntegersFromServer()
.subscribeOn(Schedulers.newThread())
.observeOn(Schedulers.computation())
.filter(integer -> {
System.out.println(Looper.getMainLooper().getThread() == Thread.currentThread());
return true;
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(integer1 -> { doSomething(integer1) });
Dans ce cas, l'extraction se produira sur un nouveau thread, le filtrage sur un thread de calcul et doSomething
sur le thread principal.
Checkout ReactiveX - Opérateur SubscribeOn pour la documentation officielle.