Gestion des événements du cycle de vie d’une activité
En général, une activité se trouve toujours dans l’un des quatre états suivants : ● Active. L’activité a été lancée par l’utilisateur, elle s’exécute au premier plan. C’est à cet état que l’on pense quand on évoque le fonctionnement d’une activité. ● En pause. L’activité a été lancée par l’utilisateur, elle s’exécute et elle est visible, mais une notification ou un autre événement occupe une partie de l’écran. Pendant ce temps, l’utilisateur voit l’activité mais peut ne pas être capable d’interagir avec elle. Lorsqu’un appel téléphonique est reçu, l’utilisateur a l’opportunité de prendre cet appel ou de l’ignorer, par exemple. ● Stoppée. L’activité a été lancée par l’utilisateur, elle s’exécute mais est cachée par d’autres activités qui ont été lancées ou vers lesquelles le système a basculé. Votre application ne pourra rien présenter d’intéressant à l’utilisateur directement : elle ne peut passer que par une Notification. ● Morte. L’activité n’a jamais été lancée (le téléphone vient d’être réinitialisé, par exemple) ou elle a été tuée, probablement à cause d’un manque de mémoire. Vie et mort d’une activité Android fera appel à votre activité en considérant les transitions entre les quatre états que nous venons de présenter. Certaines transitions peuvent provoquer plusieurs appels à votre activité, via les méthodes présentées dans cette section ; parfois, Android tuera votre application sans l’appeler. Tout ceci est assez flou et sujet à modifications : c’est la raison pour laquelle vous devez consulter attentivement la documentation officielle d’Android en plus de cette section pour décider des événements qui méritent attention et de ceux que vous pouvez ignorer. Notez que vous devez appeler les versions de la superclasse lorsque vous implémentez les méthodes décrites ici ; sinon Android peut lever une exception. onCreate() et onDestroy() Tous les exemples que nous avons vus jusqu’à maintenant ont implémenté onCreate() dans leurs sous-classes d’Activity. Cette méthode sera appelée dans les trois cas suivants : ● Lorsque l’activité est lancée pour la première fois (après le redémarrage du système, par exemple), onCreate() est appelée avec le paramètre null. ● Si l’activité s’est exécutée, puis qu’elle a été tuée, onCreate() sera appelée avec, pour paramètre, le Bundle obtenu par onSaveInstanceState() (voir plus loin). Livre Android.book Page 174 Dimanche, 8. novembre 2009 12:23 12 customer 27921 at Fri Mar 11 19:19:45 +0100 2011 Propriété de Albiri Sigue Chapitre 16 Gestion des événements du cycle de vie d’une activité 175 ● Si l’activité s’est exécutée et que vous l’ayez configurée pour qu’elle utilise des ressources différentes en fonction des états du terminal (mode portrait ou mode paysage, par exemple), elle sera recréée et onCreate() sera donc appelée. C’est dans cette méthode que vous configurez l’interface utilisateur et tout ce qui ne doit être fait qu’une seule fois, quelle que soit l’utilisation de l’activité. À l’autre extrémité du cycle de vie, onDestroy() peut être appelée lorsque l’activité prend fin, soit parce qu’elle a appelé finish() (qui « finit » l’activité), soit parce qu’Android a besoin de mémoire et l’a fermée prématurément. onDestroy() peut ne pas être appelée si ce besoin de mémoire est urgent (la réception d’un appel téléphonique, par exemple) et que l’activité se terminera quoi qu’il en soit. Par conséquent, onDestroy() est essentiellement destinée à libérer les ressources obtenues dans onCreate(). onStart(), onRestart() et onStop() Une activité peut être placée au premier plan, soit parce qu’elle vient d’être lancée, soit parce qu’elle y a été mise après avoir été cachée (par une autre activité ou la réception d’un appel, par exemple). Dans ces deux cas, c’est la méthode onStart() qui est appelée. onRestart() n’est invoquée que lorsque l’activité a été stoppée et redémarre. Inversement, onStop() est appelée lorsque l’activité va être stoppée. onPause() et onResume() La méthode onResume() est appelée immédiatement avant que l’activité ne passe au premier plan, soit parce qu’elle vient d’être lancée, soit parce qu’elle est repartie après avoir été stoppée, soit après la fermeture d’une boîte de dialogue (ouverte par la réception d’un appel, par exemple). C’est donc un bon endroit pour reconstruire l’interface en fonction de ce qui s’est passé depuis que l’utilisateur l’a vue pour la dernière fois. Si votre activité interroge un service pour savoir s’il y a de nouvelles informations (de nouvelles entrées dans un flux RSS, par exemple), onResume() est le bon moyen de rafraîchir la vue courante et, si nécessaire, de lancer un thread en arrière-plan (via un Handler, par exemple) pour modifier cette vue. Inversement, tout ce qui détourne l’utilisateur de votre activité – essentiellement l’activation d’une autre activité – provoquera l’appel d’onPause(). Vous pouvez profiter de cette méthode pour annuler tout ce que vous aviez fait dans onResume() : arrêter les threads en arrière-plan, libérer les ressources en accès exclusif que vous auriez pu prendre (l’appareil photo, par exemple), etc. Lorsque onPause() a été appelée, Android se réserve le droit de tuer à tout moment le processus de l’activité. Par conséquent, vous ne devriez pas supposer que vous pourrez recevoir d’autre événement de la part de celle-ci. Pour l’essentiel, les méthodes que nous venons de mentionner interviennent au niveau général de l’application (onCreate() relie les dernières parties de l’interface, onPause() ferme les threads en arrière-plan, etc.). Cependant, Android a pour but de fournir une apparence de simplicité de fonctionnement. Autrement dit, bien que les activités puissent aller et venir en fonction des besoins mémoire, les utilisateurs ne devraient pas savoir ce qu’il se trame. Un utilisateur qui utilisait la calculette devrait donc retrouver le ou les nombres sur lesquels il travaillait lorsqu’il la réutilise après une absence – sauf s’il avait lui-même fermé la calculette. Pour que tout cela fonctionne, les activités doivent donc pouvoir sauvegarder, rapidement et efficacement, l’état de l’instance de l’application qu’elles exécutent. En outre, comme elles peuvent être tuées à tout moment, les activités peuvent devoir sauvegarder cet état plus fréquemment qu’on ne pourrait le supposer. Réciproquement, une activité qui redémarre doit récupérer son état antérieur afin d’apparaître dans la situation où elle se trouvait précédemment. La sauvegarde de l’état d’une instance est gérée par la méthode onSaveInstanceState(), qui fournit un objet Bundle dans lequel l’activité peut placer les données qu’elle souhaite (le nombre affiché par la calculette, par exemple). L’implémentation de cette méthode doit être rapide – n’essayez pas d’en faire trop : placez simplement les données dans le Bundle et quittez la méthode. Vous pouvez récupérer l’état de l’instance dans les méthodes onCreate() et onRestoreInstanceState() : c’est vous qui décidez du moment d’appliquer cet état à votre activité – l’une ou l’autre de ces méthodes de rappel convient