RxTips – Gérer le cycle de vie Android
Problème fréquent en android : les Leaks ! ou les retour d’API sur une activité qui n’est plus affichée
githubApi.user("florent37") .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(user -> loginTextView.setText(user.getLogin()) );
Imaginons maintenant que l’appel à la ressource .user de notre api mette 10secondes à répondre,
puis que l’utilisateur ait changé d’activité avant le retour de cet appel. Le code contenu dans le subscribe s’appellera, essaiera de modifier le texte de la loginTextView, ce qui lèvra une exception !
githubApi.user("florent37") .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(user -> //cette ligne va crasher loginTextView.setText(user.getLogin()) );
Arrêter un observable
Notre solution serait d’arrêter l’exécution de notre observable lorsque l’activité n’est plus affichée.
La méthode .subscribe des objets Rx nous retournent un objet nommé Disposable (jetable en français), que nous allons utiliser pour arrêter notre traitement.
Il nous suffira d’appeler la méthode .dispose
Disposable d = Observable..... ..... .subscribe(...); d.dispose(); //arrête notre observable
CompositeDisposable
Le CompositeDisposable est en quelque sorte une liste de Disposables. On va y placer nos éléments à arrêter, et pouvoir tous les stopper d’un seul appel, en utilisant .clear()
CompositeDisposable compositeDisposable = new CompositeDisposable(); Disposable d1 = Observable...subscribe(...); compositeDisposable.add(d1); Disposable d1 = Observable...subscribe(...) compositeDisposable.add(d2); compositeDisposable.clear(); //arrête nos observable
Voici d’autres syntaxes pour ajouter nos appels à notre CompositeDisposable
CompositeDisposable compositeDisposable = new CompositeDisposable(); compositeDisposable.add(Observable... .subscribe(...)); Observable... .doOnSubscribe(d -> compositeDisposable.add(d)) .subscribe(...); compositeDisposable.clear(); //arrête nos observable
Cycle de vie Android
L’idée est d’arrêter nos appels dans le onStop() ou dans le onDestroy() de nos classes Android 🙂
public class MainActivity extends AppCompatActivity { private CompositeDisposable compositeDisposable; @Inject GithubApi githubApi; //with dagger @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //injecter la githubApi ici compositeDisposable = new CompositeDisposable(); githubApi.getUser("florent37") .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .doOnSubscribe(compositeDisposable::add) .subscribe(x -> { //afficher utilisateur }); } @Override protected void onDestroy() { compositeDisposable.clear(); super.onDestroy(); } }
Un peu perdu en RxJava ? n’hésitez pas à aller faire un tour sur notre un article d’introduction sur RxJava , ainsi que celui détaillant l’utilisation des lambdas.
Petit rappel on vient de lancer une nouvelle rubrique sur le site, où vous pouvez découvrir des livres et des Goodies Android, allez-y faire un tour 😀