Cycle de vie d'une activité

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.

Figure 1 : Un modèle simplifié Illustration du cycle de vie d'une activité.

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:

  1. L'activité se termine, car l'utilisateur ferme complètement ou en raison d'une finish() étant a appelé l'activité.
  2. 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:

  1. La méthode onPause() de l'activité A s'exécute.
  2. onCreate() de l'activité B onStart() Les méthodes onResume() s'exécutent dans l'ordre. L'activité B est désormais ciblée par l'utilisateur.
  3. 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.