Utilisation de AppCompatActivity
La classe AppCompatActivity est une sous-classe d'activité disponible à partir de la bibliothèque de support Android. Il offre une compatibilité ascendante permanente pour les fonctionnalités ajoutées à la classe d'activité dans chaque nouvelle version de la plate-forme. En tant que tel, il est considéré comme la meilleure pratique d’utiliser AppCompatActivity plutôt que la classe d’activités. Nous continuerons à le faire tout au long de ce livre, en faisant généralement référence aux classes qui étendent AppCompatActivity en tant qu’activités.
LISTING 3-3: Package de code squelette d'activité AppCompatActivity Activity
com.professionalandroid.apps.helloworld;
import android.support.v7.app.AppCompatActivity; import android.os.Bundle; public class MyActivity extends AppCompatActivity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
Le cycle de vie de l'activité
Une bonne compréhension du cycle de vie de l'activité est essentielle pour garantir que votre application offre une expérience utilisateur transparente et gère correctement ses ressources.Comme expliqué précédemment, les applications Android ne contrôlent pas leur propre durée de vie; Android Run Time gère le processus de chaque application et, par extension, celui de chaque activité qu'il contient.Bien que l'exécution gère la fin et la gestion du processus d'une activité, son état permet de déterminer la priorité de l'application parente. La priorité de l'application, à son tour, influence la probabilité que le temps d'exécution la termine et les activités qui y sont exécutées.
Les piles d’activités et la liste des véhicules les moins récemment utilisés (LRU)
L'état de chaque activité est déterminé par sa position dans la pile d'activités (ou «pile arrière»), une collection dernier entré, premier sorti, de toutes les activités en cours d'exécution. Lorsqu'une nouvelle activité commence, elle devient active et est déplacée vers le haut de la pile. Si l'utilisateur revient en arrière à l'aide du bouton Précédent ou si l'activité au premier plan est fermée, l'activité suivante de la pile se déplace vers le haut et devient active. La figure 3-2 illustre ce processus.Comme décrit précédemment dans ce chapitre, la priorité d’une application est influencée par son activité la plus prioritaire. Lorsque le gestionnaire de mémoire Android décide quelle application utiliser pour libérer des ressources, il utilise cette pile d’activités pour déterminer la priorité des applications.Lorsqu'aucune des activités d'une application n'est visible, l'application elle-même passe à la liste des unités utilisées de manière indirecte (LRU), qui est utilisée pour déterminer l'ordre dans lequel les applications seront fermées pour libérer des ressources, comme décrit précédemment.
FIGURE 3-2
États d'activité
Tout au long du cycle de vie d’une application, ses activités entrent et sortent de la pile d’activités, comme illustré dans la figure 3-2. Ce faisant, ils passent par quatre états possibles:
Actif: lorsqu'une activité se situe en haut de la pile, c'est l'activité visible, focalisée et de premier plan qui reçoit les entrées de l'utilisateur. Android tentera de le maintenir en vie à tout prix, en supprimant au besoin les applications qui possèdent des Activités plus loin dans la pile, afin de s'assurer que cette activité dispose des ressources nécessaires. Lorsqu'une autre activité devient active, celle-ci est suspendue. Lorsqu'elle n'est plus visible, elle est arrêtée, comme décrit dans les points suivants.
En pause: dans certains cas, votre activité sera visible mais ne sera pas centrée. à ce stade, il est en pause. Vous pouvez également atteindre cet état dans lequel votre application est utilisée dans un environnement multi-fenêtres, où plusieurs applications peuvent être visibles, mais seule l'activité avec laquelle l'utilisateur a interagi en dernier est considérée comme active. De même, si votre activité est précédée d'une activité transparente ou non plein écran, elle restera en état de pause. Lorsqu'elle est en pause, une activité est traitée comme si elle était active. cependant, il ne reçoit pas d’événements saisis par l’utilisateur. Dans les cas extrêmes, Android supprimera une activité mise en veille pour récupérer des ressources pour l'activité active. Lorsqu'une activité devient totalement obscurcie, elle est arrêtée. toutes les activités passent par l'état de pause avant d'être arrêtées.
Arrêté — Lorsqu'une activité n'est pas visible, elle “s'arrête”. L'activité reste en mémoire et conserve toutes les informations d'état. Cependant, il est désormais probable que le système soit arrêté lorsque le système nécessite de la mémoire. Lorsqu'une activité est à l'état arrêté, il est important de sauvegarder les données et l'état actuel de l'interface utilisateur, ainsi que d'arrêter toute opération non critique. Une fois une activité terminée ou fermée, elle devient inactive.
Inactif: après qu’une activité ait été supprimée, ainsi qu’avant son lancement, elle est inactive.Les activités inactives ont été supprimées de la pile d'activités et doivent être redémarrées avant de pouvoir être affichées et utilisées. Les transitions d'état se produisent lors d'actions utilisateur et système, ce qui signifie que votre application n'a aucun contrôle sur le moment où elles se produisent. De même, la fermeture des applications est gérée par le gestionnaire de mémoire Android, qui commence par fermer les applications contenant des activités inactives, suivies de celles qui sont arrêtées. Dans les cas extrêmes, cela supprimera ceux qui sont en pause.
Remarque
Pour assurer une expérience utilisateur transparente, les transitions entre les états doivent être invisibles pour l'utilisateur. Il ne devrait y avoir aucune différence entre une activité qui passe d’un état suspendu, arrêté ou inactif à un état actif. Il est donc important de sauvegarder tous les états de l’UI et de conserver toutes les données lorsqu’une activité est arrêtée.Il est recommandé d’effectuer des opérations de persistance d’états qui prennent beaucoup de temps (telles que des transactions de base de données ou des transferts réseau) lorsque l’activité passe à l’état arrêté (dans le gestionnaire onStop, comme décrit plus loin dans ce chapitre), plutôt que pendant la transition vers la état de pause (dans onPause).Les activités peuvent effectuer une transition fréquente et rapide entre les états actif et en pause, en particulier dans un environnement à fenêtres multiples, il est donc important que cette transition s’exécute aussi rapidement que possible. Une fois qu'une activité devient active, il convient de restaurer les valeurs enregistrées.
Comprendre les durées d'activité
Pour que les activités puissent réagir aux changements d'état, Android fournit une série de gestionnaires d'événements déclenchés lors de la transition d'une activité à travers ses durées de vie complètes, visibles et actives. La figure 3-3 résume ces durées de vie en fonction des états d'activité décrits dans la section précédente.Dans la totalité de la durée de vie d’une activité, entre la création et la destruction, elle passe en revue une ou plusieurs itérations de la durée de vie active et visible. Chaque transition déclenche les gestionnaires de méthodes décrits précédemment. Les sections suivantes examinent de plus près chacune de ces durées de vie et les événements qui les entourent.
La vie entière
La durée de vie complète de votre activité se produit entre le premier appel à onCreate et le moment de sa destruction. Il n’est pas rare qu’un processus d’activité se termine sans que le gestionnaire onDestroy correspondant soit appelé.Utilisez la méthode onCreate pour initialiser votre activité: gonflez l'interface utilisateur, obtenez des références à des fragments, allouez des références à des variables de classe, liez des données à des contrôles et démarrez les services. Si l’activité s’est arrêtée de manière inattendue au moment de l’exécution, la méthode onCreate reçoit un Objet Bundle contenant l'état enregistré lors du dernier appel à onSaveInstanceState. Vous devez utiliser cet ensemble pour restaurer l'interface utilisateur dans son état précédent, dans la méthode onCreate ou onRestoreInstanceState.Remplacez onDestroy pour nettoyer toutes les ressources créées dans onCreate et assurez-vous que toutes les connexions externes, telles que les liens de réseau ou de base de données, sont fermées.Conformément aux instructions fournies par Android pour la rédaction de code efficace, il est recommandé d’éviter la création répétée d’objets à court terme. La création et la destruction rapides d'objets obligent à une récupération de place supplémentaire, processus qui peut avoir un impact négatif direct sur l'expérience de l'utilisateur. Si votre activité crée régulièrement le même ensemble d’objets, envisagez de les créer dans la méthode onCreate, car elle n’est appelée qu’une fois au cours de la vie de l’activité.
La vie visible
La durée de vie visible d’une activité est limitée entre les appels à onStart et à onStop. Entre ces appels, votre activité sera visible par l'utilisateur, bien qu'elle puisse ne pas avoir le focus et être partiellement masquée. Les activités sont susceptibles de traverser plusieurs vies visibles tout au long de leur vie lorsqu'elles se déplacent entre le premier plan et l'arrière-plan. Depuis Android 3.0 Honeycomb (API, niveau 11), vous pouvez être sûr que l'onStop sera appelé avant la fin du processus de votre demande.La méthode onStop doit être utilisée pour suspendre ou arrêter des animations, des threads, des écouteurs de capteurs, des recherches GPS, des temporisations, des services ou tout autre processus utilisé exclusivement pour mettre à jour l'interface utilisateur. Consommer des ressources (telles que la mémoire, les cycles de la CPU ou la bande passante réseau) n’a guère d’intérêt pour mettre à jour le logiciel.Interface utilisateur quand il n'est pas visible. Utilisez la méthode onStart pour reprendre ou redémarrer ces processus lorsque l'interface utilisateur est à nouveau visible.La méthode onRestart est appelée immédiatement avant tout, sauf le premier appel à onStart. Utilisez-le pour mettre en œuvre le traitement spécial que vous souhaitez effectuer uniquement lorsque l'activité redémarre au cours de sa durée de vie.Les méthodes onStart / onStop doivent également être utilisées pour enregistrer et désenregistrer les récepteurs de diffusion utilisés exclusivement pour mettre à jour l'interface utilisateur.
La vie active
La durée de vie active commence par un appel à onResume et se termine par un appel correspondant à onPause. Une activité active est au premier plan et reçoit des événements d'entrée de l'utilisateur. Votre activité passera probablement par de nombreuses durées de vie actives avant qu’elle ne soit détruite, car elle se terminera lorsqu’une nouvelle activité sera affichée, que l’appareil s’endormira ou si l’activité perd son focus. Essayez de garder le code dans les méthodes onPause et onResume rapide et léger pour vous assurer que votre application reste réactive lors du passage au premier plan. Vous pouvez sans risque supposer que pendant la durée de vie active, onPause sera appelée avant la fin du processus.
Remarque
Si le système détermine qu'il peut être nécessaire de reprendre cet état d'activité, alors immédiatement avant onPause, un appel à onSaveInstanceState est effectué. Cette méthode offre la possibilité de sauvegarder l’état de l’UI de l’activité dans un ensemble pouvant être transmis aux méthodes onCreate et onRestoreInstanceState.Utilisez onSaveInstanceState pour enregistrer l'état de l'interface utilisateur afin de vous assurer que l'activité peut présenter la même interface utilisateur lors de sa prochaine activation. Le gestionnaire onSaveInstanceState ne sera pas appelé si le système détermine que l'état actuel ne sera pas repris - par exemple, si l'activité est fermée en appuyant sur le bouton Précédent. Depuis Android 3.0 Honeycomb (API niveau 11), l’achèvement du gestionnaire onStop marque le point au-delà duquel une activité peut être supprimée sans avertissement. Cela vous permet de déplacer toutes les opérations fastidieuses nécessaires à la sauvegarde d’état dans onStop, tout en maintenant votre charge de onPause légère et en vous concentrant sur la suspension des opérations gourmandes en mémoire ou en ressources lorsque l’activité n’est pas active. En fonction de l'architecture de votre application, cela peut inclure la suspension de threads, de processus ou de récepteurs de diffusion alors que votre activité n'est pas au premier plan.La méthode onResume correspondante doit également être légère. Vous n'avez pas besoin de recharger l'état de l'interface utilisateur ici, car cela devrait être géré par les méthodes onCreate et onRestoreInstanceState selon les besoins. Utilisez onResume pour inverser les actions effectuées dans onPause, telles que l'allocation de ressources libérées, l'initialisation ou l'enregistrement de composants supprimés ou non enregistrés, ainsi que la reprise de tout comportement suspendu.
Surveillance des changements d'état
Activité d'événement d'état d'activité Le code squelette du Listing 3-4 affiche les stubs des gestionnaires de méthode de changement d'état disponibles dans une activité, comme décrit dans la section précédente. Les commentaires dans chaque talon décrivent les actions à entreprendre lors de chaque événement de changement d'état.
LISTING 3-4 : Gestionnaires d'événements d'état d'activité
public class StateChangeMonitoringActivity extends AppCompatActivity {
// Appelé au début de la vie entière.
@Override
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
// Initialise l'activité et gonfle l'interface utilisateur.
}
// Appelé avant les durées de vie visibles suivantes // pour un processus d'activité. C'est-à-dire avant une activité
// revient à être visible après avoir été caché.
@Override
public void onRestart() { super.onRestart();
// Charge les modifications en sachant que l'activité a déjà// été visible dans ce processus.
}
// Appelé au début de la durée de vie visible.
@Override
public void onStart() { super.onStart();
// Apply any required UI change now that the Activity is visible.
// This is where you'd typically start any processes that
// are required to ensure your UI is appropriately populated and // updated.
}
// Called after onStart has finished, in cases where an Activity is
// started after having last been destroyed by the runtime rather than
// through user or programmatic action (such as the user hitting back or // your app calling finish().
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState);
// Restore UI state from the savedInstanceState.
// This bundle has also been passed to onCreate.
// Will only be called if the Activity has been // killed by the system since it was last visible.
}
// Called at the start of the active lifetime.
@Override public void onResume() { super.onResume();
// Resume any paused UI updates, threads, or processes required // by the Activity but suspended when it becomes inactive.
// At this stage, your Activity is active and receiving input // from users actions.
}
// Called at the end of the active lifetime.
@Override public void onPause() { super.onPause();
// Suspend UI updates, threads, or CPU intensive processes
// that don't need to be updated when the Activity isn't
// the active foreground Activity. Note that in multi-screen
// mode, paused Activities may still be visible, and as such // should continue performing required UI updates.
}
// Called when appropriate to save UI state changes at the // end of the active lifecycle.
@Override
public void onSaveInstanceState(Bundle savedInstanceState) { super.onSaveInstanceState(savedInstanceState);
// Save UI state changes to the savedInstanceState.
// This bundle will be passed to onCreate and
// onRestoreInstanceState if the process is
// killed and restarted by the run time. Note that
// this handler may not be called if the runtime determines // that the Activity is being "permanently" terminated.
}
// Called at the end of the visible lifetime.
@Override public void onStop() { super.onStop();
// Suspend remaining UI updates, threads, or processing // that aren't required when the Activity isn't visible.
// Persist all edits or state changes as your Activity
// may be killed at any time after onStop has // completed.
}
// Sometimes called at the end of the full lifetime.
@Override public void onDestroy() { super.onDestroy();
// Clean up any resources including ending threads, // closing database connections etc.
}