J'ai effectué la mise à niveau vers Android Studio 3.1 aujourd'hui, ce qui semble avoir ajouté quelques contrôles anti-peluche supplémentaires. L'une de ces vérifications de la charpie concerne les appels ponctuels RxJava2 subscribe()
qui ne sont pas stockés dans une variable. Par exemple, obtenir une liste de tous les joueurs de ma base de données Room:
Single.just(db)
.subscribeOn(Schedulers.io())
.subscribe(db -> db.playerDao().getAll());
Résultats dans un gros bloc jaune et cette info-bulle:
Le résultat de
subscribe
n'est pas utilisé
Quelle est la meilleure pratique pour les appels Rx uniques comme celui-ci? Devrais-je garder le Disposable
et dispose()
en mode complet? Ou devrais-je simplement @SuppressLint
et passer à autre chose?
Cela ne semble affecter que RxJava2 (io.reactivex
), RxJava (rx
) n'a pas cette peluche.
Le IDE ne connaît pas les effets potentiels de votre abonnement lorsqu'il n'est pas supprimé, il le traite donc comme potentiellement dangereux. Par exemple, votre Single
peut contenir un appel réseau, ce qui peut provoquer une fuite de mémoire si votre Activity
est abandonné pendant son exécution.
Un moyen pratique de gérer une grande quantité de Disposable
s consiste à utiliser un CompositeDisposable ; créez simplement une nouvelle variable d'instance CompositeDisposable
dans votre classe englobante, puis ajoutez tous vos éléments jetables à CompositeDisposable (avec RxKotlin, vous pouvez simplement ajouter addTo(compositeDisposable)
à tous vos éléments jetables). Enfin, lorsque vous avez terminé avec votre instance, appelez compositeDisposable.dispose()
.
Cela éliminera les avertissements de peluches et garantira que votre Disposables
sera géré correctement.
Dans ce cas, le code ressemblerait à ceci:
CompositeDisposable compositeDisposable = new CompositeDisposable();
Disposable disposable = Single.just(db)
.subscribeOn(Schedulers.io())
.subscribe(db -> db.get(1)));
compositeDisposable.add(disposable); //IDE is satisfied that the Disposable is being managed.
disposable.addTo(compositeDisposable); //Alternatively, use this RxKotlin extension function.
compositeDisposable.dispose(); //Placed wherever we'd like to dispose our Disposables (i.e. in onDestroy()).
Au moment où l'activité sera détruite, la liste des produits à usage unique sera effacée et tout ira bien.
io.reactivex.disposables.CompositeDisposable mDisposable;
mDisposable = new CompositeDisposable();
mDisposable.add(
Single.just(db)
.subscribeOn(Schedulers.io())
.subscribe(db -> db.get(1)));
mDisposable.dispose(); // dispose wherever is required
Comme suggéré, vous pouvez utiliser une variable globale CompositeDisposable
pour ajouter le résultat de l'opération subscribe.
La bibliothèque RxJava2Extensions contient des méthodes utiles pour supprimer automatiquement les éléments jetables créés de la variable CompositeDisposable
lorsqu'elle est terminée. Voir la section subscribeAutoDispose .
Dans votre cas, cela peut ressembler à ceci
SingleConsumers.subscribeAutoDispose(
Single.just(db)
.subscribeOn(Schedulers.io()),
composite,
db -> db.playerDao().getAll())
Vous pouvez vous abonner avec DisposableSingleObserver :
Single.just(db)
.subscribeOn(Schedulers.io())
.subscribe(new DisposableSingleObserver<Object>() {
@Override
public void onSuccess(Object obj) {
// work with the resulting todos...
dispose();
}
@Override
public void onError(Throwable e) {
// handle the error case...
dispose();
}});
Au cas où vous auriez besoin de disposer directement de l'objet Single
(par exemple, avant qu'il n'émette), vous pouvez implémenter la méthode onSubscribe(Disposable d)
pour obtenir et utiliser la référence Disposable
.
Vous pouvez également réaliser l'interface SingleObserver
par vous-même ou utiliser d'autres classes enfant.