·

Légalité d'un État à l'autre : éviter les exceptions IllegalStateException avec RxJava et RxLifecycle

Comme la plupart de ses homologues Android, L'application grand public de Zumper récupère des données sur Internet pour étayer la quasi-totalité des vues. En général, le protocole est simple : lorsqu’un utilisateur visite une certaine section, l’application Zumper effectue un appel réseau.  onCreate:

Code 1

Remarque : notre couche API est essentiellement une surcouche autour de La bibliothèque de mise en réseau Volley de Google.

Dans un monde parfait, doté d'un internet infiniment rapide et d'une puissance de calcul herculéenne, les requêtes API comme celle ci-dessus s'exécuteraient instantanément ; quoi que nous voulions faire dans onResponse() ou onErrorResponse Cela se produit instantanément.

Bien sûr, nous ne vivons pas dans un monde parfait et toutes nos applications doivent composer avec une fiabilité et une latence réseau loin d'être optimales. La plupart du temps, nous pouvons nous permettre de demander à nos utilisateurs d'attendre quelques secondes que les données se chargent depuis le réseau. En général, cette stratégie présente peu de risques ; les utilisateurs sont prêts à patienter quelques secondes avant de quitter la page. Mais qu'en est-il de ceux qui finissent par quitter la page ? Ce cas d'utilisation pose problème lorsqu'il est assez fréquent de devoir afficher un Fragment ou Fragment de dialogue dans l'une de vos méthodes de rappel.

Prenons l'exemple de l'application grand public de Zumper. L'un de nos principaux arguments de vente est notre fonctionnalité intégrée de vérification d'identité et d'accès au rapport de solvabilité, qui permet à un utilisateur d'obtenir son rapport de solvabilité depuis son appareil Android (ou iOS). Une fois son rapport obtenu, l'utilisateur Zumper peut consulter son score à tout moment, après avoir créé une session sécurisée.

Phone Image 1

Du point de vue du réseautage, le processus semble relativement simple :

Un extrait de Zumper's ViewCreditReportFragment.onCreate()

Code 1-1

Bien que les échanges entre le client et le serveur soient assez rapides, l'architecture décrite ci-dessus nous expose à un Exception d'état illégal si l'utilisateur fait quelque chose qui provoque le conteneur Consulter un fragment de rapport de crédit pour sauvegarder son état, comme lorsqu'on quitte la vue. Pourquoi ? Lorsque l'application appelle CreditAuthDialogFragment.show(), le gestionnaire de fragments enfants utilise ses vérifierPerteÉtat() méthode permettant de garantir que la modification de l'interface utilisateur (c'est-à-dire l'affichage de la fenêtre de dialogue) ne sera pas perdue lors de la transition Activité destruction et récréation1:

Depuis FragmentManagerImpl.java

Code 3

Alors, quand est-ce que le Gestionnaire de fragments Sauvons-nous Consulter un fragment de rapport de crédit’L'état de ? Selon le documentation, L'état peut être sauvegardé à tout moment avant destruction. En examinant la question plus en détail, vous trouverez un commentaire dans le FragmentManagerImpl.saveAllState() méthode indiquant que l'état est sauvegardé après une pause2. D'un point de vue pratique, l'hypothèse raisonnable est que l'état est sauvegardé lorsqu'une Fragment sort de la vue3.

Que pouvons-nous faire pour éviter ce plantage ? D’après la discussion ci-dessus, lorsque nous voulons effectuer une opération Transaction de fragment (par exemple, lorsque nous voulons appeler DialogFragment.show()), nous devons nous assurer que notre Consulter un fragment de rapport de crédit n'a pas encore été interrompue. À cette fin, nous nous sommes fortement appuyés sur RxJava et Cycle de vie des médicaments bibliothèques pour s'assurer que nous ne commettons pas d'erreurs. Transaction de fragmentaprès la sauvegarde de l'état. La magie, pour ainsi dire, réside dans la combinaison des fonctionnalités de RxJava. Observable.compose() méthode avec RxLifecycle RxLifecycle.bindFragment() méthode.

Pour intégrer cette magie fonctionnelle réactive (merci Netflix !), nous avons commencé à réécrire nos API réseau pour tirer parti de Observable Les flux, l'élément de base de RxJava. La transformation a donné un résultat similaire à ceci :

Code 4

Pour intégrer le composant RxLifecycle (un grand merci à Trello pour cette idée !), nous avons modifié le parent de base de Zumper. Fragment communiquer son cycle de vie via des appels à un Sujet du comportement, le même Sujet du comportement qui est transmis à RxLifecycle.bindFragment():

Code 1-2

Désormais, chaque fois que l'application grand public de Zumper effectue un appel au réseau au sein d'un Fragment, que ce soit dans une méthode de cycle de vie ou ailleurs, nous utilisons notre astucieux Observable les API et les lier au cycle de vie des Fragment en utilisant composer():

Code 6

Ce modèle de conception offre une solution syntaxiquement concise et élégante à un problème omniprésent. Bien que la migration ne soit pas encore tout à fait terminée, nous avons quasiment éliminé… Exception d'état illégalC'est là que nous avons utilisé ce modèle, ce qui a permis d'offrir une expérience utilisateur plus stable et plus satisfaisante. De plus, l'adoption d'API fonctionnelles réactives a rendu possible un code plus déclaratif et flexible, notamment pour la manipulation de collections ou l'exécution de plusieurs appels réseau séquentiels. Mais ceci, mes amis, est une autre histoire.

Notes de bas de page :

1. Voir Message d'Alex Lockwood à ce sujet pour plus d'informations sur les `FragmentTransaction`, la perte d'état et les `IllegalStateException`.

2. L'état est sauvegardé après la mise en pause dans Android API 11 (Honeycomb) et versions ultérieures. Auparavant, l'état était sauvegardé avant la mise en pause.

3. Il existe des exceptions, par exemple au sein d'un ViewPager.

jp
Issu du monde juridique, Justin s'est intéressé au développement web lors de son expérience en tant que consultant en contentieux en 2012. Après une année d'expérimentation, il a décroché son premier emploi de développeur Android professionnel, sans aucune expérience préalable sur cette plateforme. Depuis, les choses ont bien changé : Justin fait désormais partie de l'équipe de développement Android de Zumper, composée de deux personnes, et travaille à la création d'une application mobile qui a reçu les distinctions ’ Choix de la rédaction » et « Meilleur développeur ».

Trouvez votre prochain endroit