Lorsqu'un utilisateur parcourt votre application, la quitte et y retourne,
Activity
instances dans votre application passent par
différents états dans leur cycle de vie.
La classe Activity
fournit un certain nombre de rappels.
permettant à l'activité de savoir quand un état change ou que
le système crée, arrête ou réactive une activité, ou détruit
le processus dans lequel
se trouve l’activité.
Dans les méthodes de rappel de cycle de vie, vous pouvez déclarer la façon dont votre activité se comporte lorsque l'utilisateur quitte l'activité et la retourne. Par exemple, si vous si vous créez un lecteur vidéo en streaming, vous pouvez mettre la vidéo en pause, connexion réseau lorsque l'utilisateur passe à une autre application. Lorsque l'utilisateur revient, vous pouvez vous reconnecter au réseau et permettre à l'utilisateur de reprendre la lecture de la vidéo au même endroit.
Chaque rappel vous permet d'effectuer des tâches spécifiques adapté à un changement d'état donné. Le bon travail à la bonne humeur du temps et de la bonne gestion des transitions rendent votre application plus robuste et plus performante. Par exemple, une bonne implémentation des rappels de cycle de vie peut aider votre application évitez ce qui suit:
- Plantage si l'utilisateur reçoit un appel téléphonique ou passe à un autre application lorsque vous l'utilisez.
- Consommation de précieuses ressources système lorsque l'utilisateur n'est pas actif l'utilisent.
- La progression de l'utilisateur est perdue s'il quitte votre application et y revient ultérieurement.
- Plantage ou perte de la progression de l'utilisateur lorsque l'écran pivote entre les orientations paysage et portrait.
Ce document explique en détail le cycle de vie d'une activité. Le document commence en décrivant le paradigme du cycle de vie. Ensuite, il explique chacun des rappels: ce qui se passe en interne pendant leur exécution et ce que vous devez implémenter pendant ces opérations.
Il présente ensuite brièvement la relation entre l'activité l’état et la vulnérabilité d’un processus à la mort par le système. Enfin, il aborde plusieurs sujets liés aux transitions entre de l'activité.
Pour en savoir plus sur la gestion des cycles de vie, y compris des conseils sur les bonnes pratiques, consultez la section Gérer les cycles de vie à l'aide de composants tenant compte des cycles de vie et Enregistrer les états de l'interface utilisateur Pour apprendre à concevoir une application robuste et de qualité production, à l'aide des activités de avec les composants d'architecture, consultez Guide de l'architecture des applications
Concepts du cycle de vie des activités
Pour gérer les transitions entre les étapes du cycle de vie d'une activité,
La classe Activity
fournit un ensemble de six rappels de base:
onCreate()
,
onStart()
,
onResume()
,
onPause()
,
onStop()
et
onDestroy()
Le système appelle
chacun de ces rappels lorsque l'activité passe dans un nouvel état.
La figure 1 présente une représentation visuelle de ce paradigme.
Lorsque l'utilisateur commence à quitter l'activité, le système appelle des méthodes pour démanteler l'activité. Dans certains cas, l'activité n'est que partiellement est démonté et est toujours en mémoire, par exemple lorsque l'utilisateur passe à une autre application. Dans ce cas, l'activité peut toujours revenir au premier plan.
Si l'utilisateur revient à l'activité, reprend là où l'utilisateur s'était arrêté. À quelques exceptions près, les applications restreint pour Lancer des activités lors de l'exécution en arrière-plan
La probabilité qu'a le système la suppression d'un processus donné et des activités qu'il contient, de l'activité à ce moment-là. Pour en savoir plus sur la relation entre l'état et à l'éjection, consultez la section sur l'état d'activité et l'exclusion de la mémoire.
Selon la complexité de votre activité, vous n'aurez probablement pas besoin de à implémenter toutes les méthodes du cycle de vie. Cependant, il est important que les comprendre et implémenter celles qui font que votre application se comporte aux attentes des utilisateurs.
Rappels de cycle de vie
Cette section fournit des informations conceptuelles et des informations sur la mise en œuvre de rappel utilisées pendant le cycle de vie de l'activité.
Certaines actions font partie des méthodes du cycle de vie d'une activité. Toutefois, placez le code qui implémente les actions d'un composant dépendant au lieu de la méthode du cycle de vie de l'activité. Pour ce faire, vous devez pour que le composant dépendant tienne compte du cycle de vie. Pour apprendre à rendre vos composants dépendants tenant compte du cycle de vie, consultez la section Gérer les cycles de vie à l'aide de composants tenant compte des cycles de vie.
onCreate()
Vous devez implémenter ce rappel, qui se déclenche lorsque le système crée le
activité. Lors de la création de l'activité, l'état passe à l'état Created (Créée).
Dans le onCreate()
exécuter une logique de démarrage de base de l'application
ne se produit qu'une seule fois pendant toute la durée de l'activité.
Par exemple, votre
l'implémentation de onCreate()
peut lier des données à des listes, associer l'activité à un
ViewModel
,
et instancier des variables
de portée classe. Cette méthode reçoit
paramètre savedInstanceState
, qui est un Bundle
.
contenant l'état enregistré précédemment de l'activité. Si l'activité présente
n'a jamais existé auparavant, la valeur de l'objet Bundle
est nulle.
Si vous disposez d'un composant qui tient compte des cycles de vie et qui est lié au cycle de vie
votre activité, il reçoit
ON_CREATE
. La méthode annotée avec @OnLifecycleEvent
est appelée pour que votre environnement de cycle de vie soit pris en compte.
peut exécuter n'importe quel code de configuration
dont il a besoin pour l'état créé.
L'exemple suivant de la méthode onCreate()
présente la configuration fondamentale de l'activité, comme la déclaration de l'interface utilisateur
(définies dans un fichier de mise en page XML), définir des variables de membre et configurer
une partie de l'UI. Dans cet exemple, le fichier de mise en page XML transmet
l'ID de ressource R.layout.main_activity
du fichier sur
setContentView()
Kotlin
lateinit var textView: TextView // Some transient state for the activity instance. var gameState: String? = null override fun onCreate(savedInstanceState: Bundle?) { // Call the superclass onCreate to complete the creation of // the activity, like the view hierarchy. super.onCreate(savedInstanceState) // Recover the instance state. gameState = savedInstanceState?.getString(GAME_STATE_KEY) // Set the user interface layout for this activity. // The layout is defined in the project res/layout/main_activity.xml file. setContentView(R.layout.main_activity) // Initialize member TextView so it is available later. textView = findViewById(R.id.text_view) } // This callback is called only when there is a saved instance previously saved using // onSaveInstanceState(). Some state is restored in onCreate(). Other state can optionally // be restored here, possibly usable after onStart() has completed. // The savedInstanceState Bundle is same as the one used in onCreate(). override fun onRestoreInstanceState(savedInstanceState: Bundle?) { textView.text = savedInstanceState?.getString(TEXT_VIEW_KEY) } // Invoked when the activity might be temporarily destroyed; save the instance state here. override fun onSaveInstanceState(outState: Bundle?) { outState?.run { putString(GAME_STATE_KEY, gameState) putString(TEXT_VIEW_KEY, textView.text.toString()) } // Call superclass to save any view hierarchy. super.onSaveInstanceState(outState) }
Java
TextView textView; // Some transient state for the activity instance. String gameState; @Override public void onCreate(Bundle savedInstanceState) { // Call the superclass onCreate to complete the creation of // the activity, like the view hierarchy. super.onCreate(savedInstanceState); // Recover the instance state. if (savedInstanceState != null) { gameState = savedInstanceState.getString(GAME_STATE_KEY); } // Set the user interface layout for this activity. // The layout is defined in the project res/layout/main_activity.xml file. setContentView(R.layout.main_activity); // Initialize member TextView so it is available later. textView = (TextView) findViewById(R.id.text_view); } // This callback is called only when there is a saved instance previously saved using // onSaveInstanceState(). Some state is restored in onCreate(). Other state can optionally // be restored here, possibly usable after onStart() has completed. // The savedInstanceState Bundle is same as the one used in onCreate(). @Override public void onRestoreInstanceState(Bundle savedInstanceState) { textView.setText(savedInstanceState.getString(TEXT_VIEW_KEY)); } // Invoked when the activity might be temporarily destroyed; save the instance state here. @Override public void onSaveInstanceState(Bundle outState) { outState.putString(GAME_STATE_KEY, gameState); outState.putString(TEXT_VIEW_KEY, textView.getText()); // Call superclass to save any view hierarchy. super.onSaveInstanceState(outState); }
Au lieu de définir le fichier XML et de le transmettre à setContentView()
, vous pouvez
Vous pouvez créer des objets View
dans votre code d'activité et créer une
la hiérarchie des vues en insérant de nouveaux objets View
dans
ViewGroup
Vous utilisez ensuite cette mise en page en transmettant
racine ViewGroup
en setContentView()
.
Pour en savoir plus sur la création d'une interface utilisateur, consultez la
interface utilisateur.
Votre activité ne reste pas dans l'état
de l'état. Une fois l'exécution de la méthode onCreate()
terminée, l'activité passe à l'état Started (Démarré)
et le système appelle onStart()
et onResume()
dans les
succession.
onStart()
Lorsque l'activité passe à l'état "Démarrée", le système
appelle onStart()
.
Cet appel rend l'activité visible par l'utilisateur
L'application prépare l'activité pour passer au premier plan et devenir interactive.
Par exemple, c'est dans cette méthode que le code qui gère
l'UI est initialisée.
Lorsque l'activité passe à l'état "Démarrée", tout composant tenant compte du cycle de vie et lié
au cycle de vie de l'activité reçoit
ON_START
.
La méthode onStart()
se termine
et, comme c'est le cas pour l'état "Created", l'activité n'est pas conservée
à l'état "Démarré". Une fois ce rappel terminé, l'activité entre dans
l'état Resumed (Reprise) et que le système appelle
onResume()
.
onResume()
Lorsque l'activité passe à l'état "Reprise", elle s'affiche au premier plan.
le système appelle onResume()
. Il s'agit de l'état dans lequel l'application
interagit avec l'utilisateur. L'application reste dans cet état jusqu'à ce qu'il se passe quelque chose
détourner l'attention de l'application (par exemple, l'appareil qui reçoit un appel téléphonique, l'utilisateur
la navigation vers une autre activité ou l’extinction de l’écran de l’appareil.
Lorsque l'activité passe à l'état "Reprise", tout composant tenant compte du cycle de vie et lié
au cycle de vie de l'activité reçoit
ON_RESUME
. C'est là que les composants du cycle de vie
peuvent activer toute fonctionnalité devant s'exécuter tout en
le composant est visible et au premier plan, comme lors du démarrage d'une caméra
un aperçu.
Lorsqu'un événement interrompant l'activité se produit, l'activité passe à l'état Suspendu
et le système appelle
onPause()
.
Si l'activité revient à
de l'état "Reprise" à l'état "Mise en pause", le système appelle à nouveau
onResume()
. Pour cette raison, implémentez
onResume()
pour initialiser les composants que vous publiez pendant
onPause()
et d'effectuer toute autre
initialisations qui doivent se produire chaque fois que l'activité entre dans l'état
de l'état.
Voici un exemple de composant tenant compte des cycles de vie qui accède à l'appareil photo quand
le composant reçoit l'événement ON_RESUME
:
Kotlin
class CameraComponent : LifecycleObserver { ... @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun initializeCamera() { if (camera == null) { getCamera() } } ... }
Java
public class CameraComponent implements LifecycleObserver { ... @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) public void initializeCamera() { if (camera == null) { getCamera(); } } ... }
Le code précédent initialise l'appareil photo une fois que le
LifecycleObserver
reçoit l'événement ON_RESUME
. En mode multifenêtre, votre activité
peut être entièrement visible, même
lorsqu'elle est mise en veille. Par exemple, lorsque
l'application est en mode multifenêtre et l'utilisateur appuie sur la fenêtre qui ne
contenant votre activité, elle passe à l'état "Mise en pause".
Si vous
que la caméra ne soit activée que lorsque l'application est réactivée
et active au premier plan), puis initialisez l'appareil photo après l'événement
ON_RESUME
événement
vu précédemment. Si vous souhaitez que la caméra reste active pendant
est en veille, mais visible (en mode multifenêtre, par exemple),
initialiser la caméra après l'événement ON_START
.
Toutefois, le fait d'avoir l'appareil photo actif lorsque votre activité est mise en pause, il est possible qu'une autre personne puisse accéder à la caméra Reprise du mode multifenêtre. Parfois, il est nécessaire de conserver caméra activée lorsque votre activité est en pause, mais cela pourrait dégrader de l'expérience utilisateur globale.
Pour cette raison, réfléchissez bien à l'endroit où il est plus approprié de prendre le contrôle des ressources système partagées le contexte du mode multifenêtre. Pour en savoir plus sur la compatibilité avec le mode multifenêtre, procédez comme suit : consultez la section Compatibilité avec le mode multifenêtre.
Quel que soit l'événement de compilation choisi
opération d'initialisation, veillez à utiliser le cycle de vie correspondant
pour libérer la ressource. Si vous initialisez quelque chose après
l'événement ON_START
, le libérer ou l'arrêter après le
ON_STOP
. Si vous
s'initialiser après l'événement ON_RESUME
, puis relâcher après l'événement
ON_PAUSE
.
L'extrait de code précédent place le code d'initialisation de l'appareil photo dans
qui tient compte du cycle de vie. Vous pouvez insérer ce code directement dans l'activité
les rappels de cycle de vie, tels que onStart()
et
onStop()
. Toutefois, nous vous déconseillons de le faire. Ajouter cette logique
à un composant indépendant, qui tient compte du cycle de vie, vous permet de le réutiliser
sur plusieurs activités sans avoir à dupliquer le code. Pour savoir comment créer un composant tenant compte des cycles de vie, consultez
Gérer les cycles de vie à l'aide de composants tenant compte des cycles de vie
onPause()
Le système appelle cette méthode comme première indication que l'utilisateur quitte votre activité, même si cela ne signifie pas toujours que l'activité est en train d'être détruite. Elle indique que l'activité n'est plus au premier plan, mais qu'elle est reste visible si l'utilisateur est en mode multifenêtre. Une activité peut entrer dans cet état:
- Un événement qui interrompt l'exécution de l'application, comme décrit dans la section sur le rappel onResume(), met en pause l'activité en cours. Il s'agit de l'option la plus courante .
- En mode multifenêtre, une seule application est sélectionnée. et met en pause toutes les autres applications.
- L'ouverture d'une nouvelle activité semi-transparente, telle qu'une boîte de dialogue, met en pause l'activité qu’elle couvre. Tant que l'activité est partiellement visible, mais pas au premier plan, reste en pause.
Lorsqu'une activité est mise en pause, tout composant tenant compte du cycle de vie et lié
au cycle de vie de l'activité reçoit
ON_PAUSE
. C'est ici
les composants du cycle de vie peuvent arrêter toute fonctionnalité qui n'a pas besoin de s'exécuter
lorsque le composant n'est pas au premier plan (par exemple, en arrêtant une caméra
un aperçu.
Utilisez la méthode onPause()
pour mettre en veille ou
ajuster les opérations qui ne peuvent pas se poursuivre
ou qui peuvent se poursuivre en modération,
lorsque Activity
est "Suspendu" et que vous
devrait reprendre sous peu.
Vous pouvez également utiliser la méthode onPause()
pour
libérer des ressources système, des poignées sur des capteurs (comme le GPS) ou toute ressource
affecter l'autonomie de la batterie lorsque votre activité est en pause et que l'utilisateur
qui en ont besoin.
Toutefois, comme indiqué dans la section concernant onResume()
, une mise en veille
l'activité peut rester entièrement visible si l'application est en mode multifenêtre.
Envisagez d'utiliser onStop()
au lieu de onPause()
pour libérer ou ajuster complètement les paramètres.
Ressources et opérations liées à l'interface utilisateur pour une meilleure compatibilité avec le mode multifenêtre.
L'exemple suivant de LifecycleObserver
qui réagit à l'événement ON_PAUSE
est l'équivalent de l'événement précédent
Exemple d'événement ON_RESUME
, en relâchant la caméra qui s'initialise après
l'événement ON_RESUME
est reçu:
Kotlin
class CameraComponent : LifecycleObserver { ... @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) fun releaseCamera() { camera?.release() camera = null } ... }
Java
public class JavaCameraComponent implements LifecycleObserver { ... @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) public void releaseCamera() { if (camera != null) { camera.release(); camera = null; } } ... }
Dans cet exemple, le code de version de l'appareil photo est placé après la balise
LifecycleObserver
reçoit l'événement ON_PAUSE
.
L'exécution de onPause()
est très brève et
n'offre pas nécessairement assez de temps pour effectuer des opérations d'enregistrement. Pour cette
raison, n'utilisez pas onPause()
pour enregistrer l'application ou l'utilisateur
de données, effectuer des appels réseau ou exécuter des transactions de base de données. Un tel travail pourrait ne pas
avant la fin de la méthode.
Effectuez plutôt des opérations d'arrêt à forte charge pendant
onStop()
Pour en savoir plus,
sur les opérations appropriées à effectuer
onStop()
, consultez la section suivante. Pour en savoir plus sur l'enregistrement
consultez la section Enregistrer et restaurer l'état.
Fin de la méthode onPause()
ne signifie pas que l'activité reste mise en pause. Il s'agit plutôt de l'activité
reste dans cet état jusqu'à ce que l'activité reprenne ou qu'elle soit complètement
invisible pour l'utilisateur. Si l'activité reprend, le système appelle à nouveau
le rappel onResume()
.
Si le
l'activité revient de l'état "Mise en pause" à l'état "Reprise", le système conserve
l'instance Activity
résidente en mémoire, en rappelant
cette instance lorsque le système appelle onResume()
.
Dans ce scénario, vous n'avez pas besoin de réinitialiser les composants créés lors des
méthodes de rappel conduisant à l'état "Reprise". Si l'activité devient
complètement invisible, le système appelle
onStop()
onStop()
Lorsque votre activité n'est plus visible par l'utilisateur, elle entre
SOver, et le système appelle
onStop()
. Cela peut se produire lorsqu'une activité nouvellement lancée couvre la totalité de l'écran. La
le système appelle aussi onStop()
lorsque l'exécution de l'activité est terminée
et est sur le point de s'arrêter.
Lorsque l'activité passe à l'état "Arrêtée", tout composant tenant compte du cycle de vie et lié
au cycle de vie de l'activité reçoit
ON_STOP
. C'est ici
les composants du cycle de vie peuvent arrêter toute fonctionnalité qui n'a pas besoin de s'exécuter
alors que le composant
n'est pas visible à l'écran.
Dans la méthode onStop()
, relâchez ou ajustez le paramètre.
les ressources inutiles lorsque l'application n'est pas visible par l'utilisateur. Par exemple, votre application peut
suspendre les animations ou passer des mises à jour de position précises à des mises à jour de position plus ou moins précises. En utilisant
onStop()
au lieu de onPause()
signifie que le travail lié à l'interface utilisateur se poursuit même lorsque l'utilisateur consulte votre activité en mode multifenêtre.
.
Utiliser également onStop()
d'effectuer des opérations d'arrêt qui nécessitent
une utilisation intensive du processeur. Par exemple, si
vous ne trouvez pas le meilleur moment pour enregistrer
des informations dans une base de données,
vous pouvez le faire pendant onStop()
. La
l'exemple suivant montre une implémentation
onStop()
qui enregistre le contenu d'un
le brouillon de la note vers l'espace de stockage persistant:
Kotlin
override fun onStop() { // Call the superclass method first. super.onStop() // Save the note's current draft, because the activity is stopping // and we want to be sure the current note progress isn't lost. val values = ContentValues().apply { put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText()) put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle()) } // Do this update in background on an AsyncQueryHandler or equivalent. asyncQueryHandler.startUpdate( token, // int token to correlate calls null, // cookie, not used here uri, // The URI for the note to update. values, // The map of column names and new values to apply to them. null, // No SELECT criteria are used. null // No WHERE columns are used. ) }
Java
@Override protected void onStop() { // Call the superclass method first. super.onStop(); // Save the note's current draft, because the activity is stopping // and we want to be sure the current note progress isn't lost. ContentValues values = new ContentValues(); values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText()); values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle()); // Do this update in background on an AsyncQueryHandler or equivalent. asyncQueryHandler.startUpdate ( mToken, // int token to correlate calls null, // cookie, not used here uri, // The URI for the note to update. values, // The map of column names and new values to apply to them. null, // No SELECT criteria are used. null // No WHERE columns are used. ); }
L'exemple de code précédent utilise directement SQLite. Toutefois, nous vous recommandons d'utiliser Room, une bibliothèque de persistance qui fournit une couche d'abstraction sur SQLite. Pour apprendre les avantages de Room et comment l'implémenter dans votre application, consultez les Bibliothèque Room Persistence .
Lorsque votre activité passe à l'état "Arrêtée", Activity
est conservé en mémoire: il conserve tous les états et membres
mais n'est pas rattaché au gestionnaire de fenêtres. Lorsque l'activité
CV, il se souvient
de ces informations.
Vous n'avez pas besoin de
Réinitialiser les composants créés lors de l'une des méthodes de rappel
conduisant à l'état "Reprise". Le système assure également le suivi de l'état actuel
pour chaque objet View
de la mise en page. Par conséquent, si
l'utilisateur saisit du texte dans un widget EditText
, qui
est conservé. Vous n'avez donc pas besoin de l'enregistrer ni de le restaurer.
Remarque : Une fois votre activité arrêtée, le système
peut détruire le processus qui contient l'activité si le système
doit récupérer de la mémoire.
Même si le système détruit le processus pendant que l'activité
est arrêté, le système conserve toujours l'état de View
des objets, comme du texte dans un widget EditText
,
Bundle
(un blob de paires clé-valeur) et les restaure.
si l'utilisateur revient à l'activité. Pour
pour en savoir plus sur la restauration d'une activité renvoyée par un utilisateur, consultez la
sur la page Enregistrer et restaurer l'état.
À l'état "Arrêtée", l'activité revient pour interagir avec
ou si l'activité est terminée et disparaît. Si l'activité survient
le système appelle onRestart()
.
Si l'exécution de Activity
est terminée, le système appelle
onDestroy()
onDestroy()
onDestroy()
est appelé avant la méthode
l'activité est détruite. Le système invoque ce rappel pour l'une des deux raisons suivantes:
-
L'activité se termine, car l'utilisateur ferme complètement
ou en raison d'une
finish()
étant a appelé l'activité. - Le système est en train de détruire temporairement l'activité en raison d'une configuration comme la rotation de l'appareil ou l'activation du mode multifenêtre.
Lorsque l'activité passe à l'état "Détruit", tout composant tenant compte du cycle de vie et lié
au cycle de vie de l'activité reçoit
ON_DESTROY
. C'est ici
les composants du cycle de vie peuvent nettoyer tout ce dont ils ont besoin avant que
Activity
est détruit.
Au lieu de placer une logique dans votre Activity
pour déterminer la raison de sa destruction,
utilisez un objet ViewModel
pour contenir
des données pertinentes sur la vue pour votre Activity
. Si Activity
est recréé
en raison d'une modification de la configuration, ViewModel
n'a rien à faire, car
il est conservé et transmis à l'instance Activity
suivante.
Si Activity
n'est pas recréé, ViewModel
a le
la méthode onCleared()
appelée, où
il peut nettoyer toutes les données
dont il a besoin avant d'être détruits. Vous pouvez faire la distinction entre ces deux scénarios à l'aide de la
isFinishing()
.
Si l'activité se termine, onDestroy()
est le rappel de cycle de vie final que
de l'activité. Si onDestroy()
est appelé à la suite d'une configuration
le système crée immédiatement une instance d'activité, puis appelle
<ph type="x-smartling-placeholder"></ph>
onCreate()
sur cette nouvelle instance dans la nouvelle configuration.
Le rappel onDestroy()
libère toutes les ressources qui n'ont pas été libérées précédemment
comme onStop()
.
État de l'activité et exclusion de la mémoire
Le système tue les processus quand il doit libérer de la RAM. La probabilité que le système l'arrêt d'un processus donné dépend de l'état du processus à un moment donné. État du processus dépend de l'état de l'activité en cours d'exécution dans le processus. Le tableau 1 montre les corrélations entre l'état de processus et l'activité. l'état et la probabilité que le système arrête le processus. Ce tableau ne s'applique que si un processus n'exécute pas d'autres types de composants d'application.
Probabilité de meurtre | État du processus | État final de l'activité |
---|---|---|
La plus faible | Premier plan (avoir ou sur le point de se concentrer) | A repris |
Faible | Visible (pas de mise au point) | Démarré/Mis en veille |
Plus haut | Arrière-plan (invisible) | Arrêté |
La plus élevée | Vide | Détruit |
Tableau 1. Relation entre le cycle de vie du processus et l'état de l'activité.
Le système n'arrête jamais une activité directement pour libérer de la mémoire. Au lieu de cela, il tue le processus dans lequel l'activité s'exécute, en détruisant non seulement l'activité mais aussi de tout ce qui s'exécute dans le processus. Pour savoir comment préserver et restaurer l'état de l'interface utilisateur de votre activité en cas d'arrêt de processus déclenché par le système consultez la section Enregistrer et restaurer l'état.
L'utilisateur peut également arrêter un processus en utilisant le Gestionnaire d'applications, sous Paramètres, pour fermer l'application correspondante.
Pour en savoir plus sur les processus, consultez Processus et threads présentation.
Enregistrer et restaurer l'état temporaire de l'interface utilisateur
Un utilisateur s'attend à ce que l'état de l'interface utilisateur d'une activité reste le même tout au long d'une un changement de configuration, comme une rotation ou un passage en mode multifenêtre. Toutefois, le système détruit l'activité par défaut lorsqu'une telle configuration se produit, effaçant tout état de l'UI stocké dans l'instance d'activité.
De même, un utilisateur s'attend à ce que l'état de l'interface utilisateur reste le même s'il passer de votre application à une autre, puis revenir à votre application ; plus tard. Toutefois, le système peut détruire le processus de votre application utilisateur est absent et votre activité est interrompue.
Lorsque des contraintes système détruisent l'activité, préservez la
l'état temporaire de l'UI de l'utilisateur à l'aide d'une combinaison
ViewModel
,
<ph type="x-smartling-placeholder"></ph>
onSaveInstanceState()
et/ou un stockage local. Pour en savoir plus sur les attentes des utilisateurs par rapport à celles du système
et comment préserver au mieux les données d'état complexes de l'interface utilisateur
activité déclenchée par le système et arrêt du processus, voir la section
Enregistrer les états de l'interface utilisateur
Cette section décrit l'état d'une instance et explique comment implémenter
La méthode onSaveInstance()
, qui est un rappel sur l'activité elle-même. Si votre
Les données de l'UI sont légères. Vous pouvez utiliser onSaveInstance()
seul pour conserver l'UI
en cas de changement de configuration ou d'arrêt de processus déclenché par le système.
Mais comme onSaveInstance()
entraîne des coûts de sérialisation/désérialisation,
dans la plupart des cas, vous utilisez à la fois ViewModel
et onSaveInstance()
,
décrits dans
Enregistrer les états de l'interface utilisateur
Remarque : Pour en savoir plus sur les modifications de configuration, découvrez comment limiter l'activité une recréation si nécessaire et comment réagir à ces modifications de configuration Consultez le système et Jetpack Compose, consultez la Page Gérer les modifications de configuration.
État de l'instance
Dans certains cas, votre activité peut être détruite par une application normale.
comportement, comme lorsque l'utilisateur appuie sur le bouton Retour ou votre activité
signale sa propre destruction en appelant
finish()
.
Lorsque votre activité est détruite, car l'utilisateur appuie sur "Retour"
ou que l'activité se termine elle-même, à la fois le concept de système
cette instance Activity
disparaît définitivement. Dans ces
les attentes de l'utilisateur correspondent au comportement du système, et vous ne devez pas
n’avez pas de travail
supplémentaire à faire.
Toutefois, si le système détruit l'activité en raison de contraintes système (comme
un changement de configuration ou une pression sur la mémoire), bien que le modèle
Activity
a disparu, le système se souvient qu'elle existait. Si l'utilisateur tente
revenez à l'activité, le système crée une instance
activité à l'aide d'un ensemble de données enregistrées décrivant l'état de l'activité
quand il a été détruit.
Les données enregistrées que le système utilise pour restaurer le
l'état précédent est appelé état de l'instance. Il s'agit d'un recueil
paires clé-valeur stockées dans un objet Bundle
. Par défaut,
le système utilise l'état d'instance Bundle
pour enregistrer des informations
sur chaque objet View
dans la mise en page de votre activité, par exemple
la valeur textuelle saisie dans
Widget EditText
.
Si votre instance d'activité est détruite et recréée, l'état de la mise en page est à son état précédent sans que vous n'ayez besoin de code. Toutefois, activité peut contenir d'autres informations d'état que vous souhaitez restaurer, par exemple des variables de membre qui suivent la progression de l'utilisateur dans l'activité.
Remarque : Pour que le système Android puisse restaurer l'état
les vues de votre activité, chacune d'entre elles doit posséder un identifiant unique, fourni par
l'attribut android:id
.
Un objet Bundle
n'est pas approprié pour conserver plus d'une
une quantité minime de données, car elle nécessite une sérialisation sur le thread principal et consomme
la mémoire des processus système. Pour préserver plus d'une très petite quantité de données,
adopter une approche combinée pour conserver les données, en utilisant des ressources
le stockage, la méthode onSaveInstanceState()
et
La classe ViewModel
, comme décrit dans la section
Enregistrer les états de l'interface utilisateur
Enregistrer un état d'interface utilisateur simple et léger avec onSaveInstanceState()
Lorsque votre activité commence à s'arrêter, le système appelle la méthode
onSaveInstanceState()
permettant à votre activité d'enregistrer des informations d'état dans un état d'instance
d'un bundle. L'implémentation par défaut de cette méthode enregistre
des informations sur l'état de la hiérarchie des vues de l'activité, telles que
du texte dans un widget EditText
ou la position de défilement d'un
Widget ListView
Pour enregistrer d'autres informations sur l'état de l'instance pour votre activité, remplacez
onSaveInstanceState()
et ajoutez des paires clé/valeur à l'objet Bundle
enregistré
au cas où votre activité serait détruite de manière inattendue. Lorsque vous remplacez
onSaveInstanceState()
, vous devez appeler l'implémentation de la super-classe
si vous souhaitez que l'implémentation par défaut enregistre l'état de la hiérarchie des vues.
Ce processus est illustré dans l'exemple suivant :
Kotlin
override fun onSaveInstanceState(outState: Bundle?) { // Save the user's current game state. outState?.run { putInt(STATE_SCORE, currentScore) putInt(STATE_LEVEL, currentLevel) } // Always call the superclass so it can save the view hierarchy state. super.onSaveInstanceState(outState) } companion object { val STATE_SCORE = "playerScore" val STATE_LEVEL = "playerLevel" }
Java
static final String STATE_SCORE = "playerScore"; static final String STATE_LEVEL = "playerLevel"; // ... @Override public void onSaveInstanceState(Bundle savedInstanceState) { // Save the user's current game state. savedInstanceState.putInt(STATE_SCORE, currentScore); savedInstanceState.putInt(STATE_LEVEL, currentLevel); // Always call the superclass so it can save the view hierarchy state. super.onSaveInstanceState(savedInstanceState); }
Remarque:
onSaveInstanceState()
n'est pas
appelé lorsque l'utilisateur ferme explicitement l'activité ou, dans d'autres cas, lorsque
finish()
est appelé.
Pour enregistrer des données persistantes, telles que les préférences utilisateur ou les données d'une base de données,
saisir les opportunités appropriées lorsque
votre activité est au premier plan.
Si aucune opportunité ne se présente, enregistrez les données persistantes pendant le
onStop()
.
Restaurer l'état de l'interface utilisateur de l'activité à l'aide de l'état d'instance enregistré
Lorsque votre activité est recréée après sa destruction précédente, vous
peut récupérer l'état enregistré de votre instance à partir de la Bundle
que le
le système transmet à votre activité. Les
onCreate()
et
<ph type="x-smartling-placeholder"></ph>
onRestoreInstanceState()
reçoivent le même Bundle
, qui contient le paramètre
des informations sur l'état de l'instance.
Comme la méthode onCreate()
est
vous demande si le système crée une instance de votre activité
ou en recréant un précédent, vous devez vérifier si l'état Bundle
est nulle avant que vous ne tentiez de le lire. Si elle est nulle, alors le système
consiste à créer une instance de l'activité, au lieu de restaurer
la précédente qui a été détruite.
L'extrait de code suivant vous montre comment restaurer certaines
données d'état dans onCreate()
:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Always call the superclass first // Check whether we're recreating a previously destroyed instance. if (savedInstanceState != null) { with(savedInstanceState) { // Restore value of members from saved state. currentScore = getInt(STATE_SCORE) currentLevel = getInt(STATE_LEVEL) } } else { // Probably initialize members with default values for a new instance. } // ... }
Java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Always call the superclass first // Check whether we're recreating a previously destroyed instance. if (savedInstanceState != null) { // Restore value of members from saved state. currentScore = savedInstanceState.getInt(STATE_SCORE); currentLevel = savedInstanceState.getInt(STATE_LEVEL); } else { // Probably initialize members with default values for a new instance. } // ... }
Au lieu de restaurer l'état
onCreate()
, vous pouvez choisir d'implémenter
onRestoreInstanceState()
, que le système appelle après la
onStart()
. Le système appelle
onRestoreInstanceState()
que s'il existe un état enregistré à restaurer. Vous devez donc
il n'est pas nécessaire de vérifier si Bundle
est nul.
Kotlin
override fun onRestoreInstanceState(savedInstanceState: Bundle?) { // Always call the superclass so it can restore the view hierarchy. super.onRestoreInstanceState(savedInstanceState) // Restore state members from saved instance. savedInstanceState?.run { currentScore = getInt(STATE_SCORE) currentLevel = getInt(STATE_LEVEL) } }
Java
public void onRestoreInstanceState(Bundle savedInstanceState) { // Always call the superclass so it can restore the view hierarchy. super.onRestoreInstanceState(savedInstanceState); // Restore state members from saved instance. currentScore = savedInstanceState.getInt(STATE_SCORE); currentLevel = savedInstanceState.getInt(STATE_LEVEL); }
Attention: Appelez toujours l'implémentation de super-classe de
onRestoreInstanceState()
afin que l'implémentation par défaut puisse restaurer l'état de la hiérarchie des vues.
Naviguer entre les activités
Une application est susceptible d'entrer et de quitter une activité, peut-être plusieurs fois, au cours d'une la durée de vie de l'application (par exemple, lorsque l'utilisateur appuie sur le bouton "Retour" de l'appareil) ; ou l'activité lance une autre activité.
Cette section aborde les sujets que vous devez connaître pour mettre en œuvre des transitions d'activités réussies. Ces sujets incluent le lancement d'une activité à partir d'une autre activité, l'enregistrement d'une activité et restaurer l'état de l'activité.
Démarrer une activité à partir d'une autre
Une activité doit souvent démarrer une autre activité à un moment donné. Ce besoin survient, par exemple, lorsqu'une application doit passer de l'écran actuel une nouvelle.
Selon que votre activité souhaite obtenir un résultat de la nouvelle activité
sur le point de commencer, vous pouvez lancer la nouvelle activité en utilisant
startActivity()
ou la
startActivityForResult()
. Dans les deux cas, vous transmettez un objet Intent
.
L'objet Intent
spécifie la valeur exacte
activité que vous souhaitez lancer ou décrit le type d'action que vous souhaitez effectuer.
Le système sélectionne pour vous l'activité appropriée, qui peut être
à partir d'une autre application. Un objet Intent
peut
transportent également de petites quantités de
données qui seront utilisées par l’activité démarrée.
Pour en savoir plus sur la classe Intent
, consultez
Intents et intention
Filtres.
startActivity()
Si l'activité nouvellement démarrée n'a pas besoin de renvoyer de résultat, l'activité en cours peut la démarrer
en appelant la méthode
startActivity()
.
Lorsque vous travaillez dans votre propre application, il suffit souvent de lancer une activité connue.
Par exemple, l'extrait de code suivant montre comment lancer une activité appelée
SignInActivity
Kotlin
val intent = Intent(this, SignInActivity::class.java) startActivity(intent)
Java
Intent intent = new Intent(this, SignInActivity.class); startActivity(intent);
Votre application peut également vouloir effectuer certaines actions, comme envoyer un e-mail, un SMS ou une mise à jour de votre état, en utilisant les données de votre activité. Dans ce cas, il est possible que votre application n'ait pas ses propres activités Vous pouvez donc exploiter les activités fournies par d'autres applications sur l'appareil, peut effectuer ces actions à votre place.
C'est là que les intents sont vraiment utiles. Vous pouvez créer un qui décrit l'action que vous souhaitez effectuer et que le système lance l'action l'activité d'une autre application. Si plusieurs activités peuvent gérer l'intent, l'utilisateur peut alors choisir laquelle utiliser. Par exemple, si vous souhaitez autoriser l'utilisateur à envoyer un e-mail, vous pouvez créer l'intent suivant:
Kotlin
val intent = Intent(Intent.ACTION_SEND).apply { putExtra(Intent.EXTRA_EMAIL, recipientArray) } startActivity(intent)
Java
Intent intent = new Intent(Intent.ACTION_SEND); intent.putExtra(Intent.EXTRA_EMAIL, recipientArray); startActivity(intent);
L'élément EXTRA_EMAIL
supplémentaire ajouté à l'intent est un tableau de chaînes de
les adresses e-mail auxquelles l'e-mail doit être envoyé. Lorsqu'une application de messagerie
répond à cet intent, il lit le tableau de chaînes fourni dans l'extra et
place les adresses dans le champ "À" du formulaire de rédaction d'e-mail. Dans ce
l'activité de l'application de messagerie démarre,
et lorsque l'utilisateur a terminé,
votre activité reprend.
startActivityForResult()
Parfois, vous souhaitez obtenir le résultat d'une activité lorsqu'elle se termine. Par exemple, vous pouvez commencer
une activité qui permet à l'utilisateur de
choisir une personne dans une liste de contacts. Lorsqu'elle se termine, la fonction renvoie
qui a été sélectionnée. Pour ce faire, appelez la méthode
startActivityForResult(Intent, int)
, où
le paramètre "Entier" identifie l'appel.
Cet identifiant permet de distinguer les appels multiples de
startActivityForResult(Intent, int)
de la même activité. Il ne s'agit pas d'un identifiant global
et ne risque pas d'entrer en conflit avec d'autres applications ou activités. Le résultat est renvoyé dans votre
onActivityResult(int, int, Intent)
.
Lorsqu'une activité enfant se ferme, elle peut appeler setResult(int)
pour
renvoyer les données à son parent.
L'activité enfant doit fournir un code de résultat, qui peut être
RESULT_CANCELED
, RESULT_OK
ou toute valeur personnalisée
à partir de RESULT_FIRST_USER
.
De plus,
l'activité enfant peut éventuellement renvoyer un Intent
contenant toutes les données supplémentaires qu'il souhaite. L'activité parent utilise le
onActivityResult(int, int, Intent)
, ainsi que l'identifiant entier de l'activité parent à l'origine
fournies, pour recevoir les informations.
Si l'activité d'un enfant échoue pour quelque raison que ce soit (plantage, par exemple),
reçoit un résultat avec le code RESULT_CANCELED
.
Kotlin
class MyActivity : Activity() { // ... override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { // When the user center presses, let them pick a contact. startActivityForResult( Intent(Intent.ACTION_PICK,Uri.parse("content://contacts")), PICK_CONTACT_REQUEST) return true } return false } override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) { when (requestCode) { PICK_CONTACT_REQUEST -> if (resultCode == RESULT_OK) { // A contact was picked. Display it to the user. startActivity(Intent(Intent.ACTION_VIEW, intent?.data)) } } } companion object { internal val PICK_CONTACT_REQUEST = 0 } }
Java
public class MyActivity extends Activity { // ... static final int PICK_CONTACT_REQUEST = 0; public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { // When the user center presses, let them pick a contact. startActivityForResult( new Intent(Intent.ACTION_PICK, new Uri("content://contacts")), PICK_CONTACT_REQUEST); return true; } return false; } protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == PICK_CONTACT_REQUEST) { if (resultCode == RESULT_OK) { // A contact was picked. Display it to the user. startActivity(new Intent(Intent.ACTION_VIEW, data)); } } } }
Coordination des activités
Lorsqu'une activité en démarre une autre, elles subissent toutes les deux des transitions de cycle de vie. La première activité cesse de fonctionner et passe à l'état "Mise en pause" ou "Arrêtée", tandis que l'autre l'activité est créée. Si ces activités partagent des données sauvegardées sur le disque ou ailleurs, il est il est important de comprendre que la première activité n'est pas complètement interrompue avant la seconde. est créé. Le processus de démarrage de la deuxième chevauche plutôt le processus de en arrêtant la première.
L'ordre des rappels de cycle de vie est bien défini, en particulier lorsque les deux activités sont dans le même processus, c'est-à-dire dans la même application, et que l'un démarre l'autre. Voici l'ordre des opérations qui se produisent Lorsque l'activité A lance l'activité B:
- La méthode
onPause()
de l'activité A s'exécute. onCreate()
de l'activité BonStart()
Les méthodesonResume()
s'exécutent dans l'ordre. L'activité B est désormais ciblée par l'utilisateur.- Si l'activité A n'est plus visible à l'écran, sa méthode
onStop()
s'exécute.
Cette séquence de rappels de cycle de vie vous permet de gérer la transition des informations d'une activité à une autre.