onStop — masquage d'Activity dans le cycle de vie Android

Auteur : IT Sectr Publié le : 2026-03-04 Temps de lecture : 9 min

onStop — une méthode du cycle de vie de l'Activity dans Android, appelée par le système lorsque l'Activity cesse d'être visible pour l'utilisateur. L'Activity passe à l'état Stopped après qu'une nouvelle Activity la recouvre complètement, ou lors de la minimisation de l'application. Dans la méthode onStop, le développeur doit arrêter les animations, libérer les ressources de la caméra et des capteurs, et sauvegarder les brouillons des données saisies. Selon Android Vitals (Google, 2025), un traitement correct de onStop réduit le nombre d'ANR (Application Not Responding) lors de la minimisation de l'application de 35 %. Après onStop, le système peut appeler onRestart (retour à l'écran) ou onDestroy (arrêt complet). La documentation Android Developers sur le cycle de vie de l'Activity décrit onStop comme la frontière entre l'état visible et invisible.

Points essentiels

  • onStop — méthode appelée lorsque l'Activity perd complètement la visibilité, mais l'Activity est toujours en mémoire.
  • Après onStop, l'Activity passe à l'état Stopped — vivante en mémoire, mais pas visible et n'interagit pas avec l'utilisateur.
  • Le système peut appeler onRestart → onStart → onResume lors du retour à l'Activity ou onDestroy à la fin.
  • Dans onStop, il est nécessaire de libérer des ressources : arrêter les animations, désactiver les capteurs et la caméra, sauvegarder les données intermédiaires.
  • L'implémentation correcte de onStop est un facteur clé de la stabilité de l'application lors du multitâche et de la minimisation.

Qu'est-ce que onStop dans Android ?

onStop — une méthode de callback de la classe AppCompatActivity (et de son prédécesseur Activity), appelée par le système d'exploitation Android lorsque l'Activity cesse d'être complètement visible pour l'utilisateur. À ce moment, l'Activity est masquée par une autre Activity, une fenêtre de dialogue, le lanceur système ou l'écran de verrouillage. Du point de vue du cycle de vie, onStop suit onPause et signale que l'Activity n'est plus visible à l'écran, bien que l'objet Activity et son état restent en mémoire.

Lorsque l'Activity passe à l'état Stopped (arrêtée), elle conserve son état dans la RAM — tous les champs, la hiérarchie des vues et la ViewModel restent accessibles. Cela distingue Stopped de l'état Destroyed (détruit), où l'Activity est complètement supprimée. L'interface système peut tuer le processus de l'application à l'état Stopped en cas de manque de mémoire — c'est ce qu'on appelle la mort du processus. Le développeur doit sauvegarder les données critiques (brouillons, position de défilement) dans onSaveInstanceState(), qui est appelé avant onStop, pour garantir la restauration en cas de mort du processus.

Selon le Document de Définition de Compatibilité Android (CDD) pour la version 14+, un processus à l'état Stopped a une priorité réduite pour être tué par l'OOM Killer — inférieure aux processus en phase Background, mais supérieure aux processus en cache. Selon les statistiques de Google, 68 % des cas de mort de processus se produisent lorsque l'Activity est à l'état Stopped, et non Paused.

Quand onStop est-il appelé : scénarios et ordre

onStop est appelé lorsque l'Activity perd complètement la visibilité, quelle qu'en soit la raison : démarrage d'une nouvelle Activity au-dessus de l'actuelle, minimisation de l'application (appui sur Home), verrouillage de l'écran, appel entrant ou ouverture d'une boîte de dialogue système. Dans tous ces cas, l'Activity reçoit d'abord onPause (perte partielle du focus), puis onStop (perte totale de visibilité).

Scénarios principaux d'appel d'onStop :

  • Démarrage d'une nouvelle Activity au-dessus de l'actuelle — l'Activity actuelle reçoit onPause, puis onStop ; la nouvelle Activity passe par onCreate → onStart → onResume.
  • Minimisation de l'application (Home) — l'Activity passe à onPause → onStop en 200 à 300 ms, reste en mémoire à l'état Stopped.
  • Verrouillage de l'écran — le système appelle onPause → onStop car l'écran de verrouillage recouvre complètement l'Activity.
  • Appel entrant — l'application téléphone (Dialer) se lance au-dessus, l'Activity actuelle passe à onStop.
  • Passage à une autre application (Applications récentes) — l'Activity est masquée, reçoit onStop, mais reste dans le cache des processus.

Il est important de comprendre que onStop n'est pas appelé lors de la rotation de l'écran — dans ce cas, l'Activity est détruite (onPause → onStop → onDestroy) et recréée (onCreate → onStart → onResume). L'exception est le flag android:configChanges="orientation" dans le manifeste, qui empêche la recréation de l'Activity et appelle à la place onConfigurationChanged().

onStop dans le cycle de vie de l'Activity

onStop occupe une place centrale dans la séquence du cycle de vie de l'Activity entre l'état visible et invisible. La séquence complète : onCreate → onStart → onResume → (état actif) → onPause → onStop → onDestroy (ou onRestart → onStart → onResume lors du retour).

ÉtatMéthodeVisibilitéInteractionMémoire
CreatedonCreateNonNonAllouée
StartedonStartPartielleNonComplete
ResumedonResumeCompleteOuiComplete
PausedonPausePartielleNonComplete
StoppedonStopNonNonComplete*
DestroyedonDestroyNonNonLibérée

*À l'état Stopped, l'Activity est conservée en mémoire mais peut être tuée par le système en cas de manque de ressources. La priorité de suppression des processus Stopped est l'avant-dernière, au-dessus seulement des processus vides en cache.

onStop et onSaveInstanceState : Le système appelle onSaveInstanceState(Bundle) avant onStop pour sauvegarder l'état dynamique de l'interface. Le développeur surcharge cette méthode pour sauvegarder dans le Bundle les valeurs des champs de saisie, la position du RecyclerView et les éléments sélectionnés. Même si l'Activity n'est pas détruite (l'utilisateur a simplement minimisé et est revenu), le Bundle est passé à onCreate lors des changements de configuration. Google recommande de sauvegarder uniquement l'état transitoire de l'interface — pas les données du dépôt ou de la ViewModel, qui vivent en dehors de l'Activity.

Quelles ressources libérer dans onStop

Dans onStop, le développeur doit libérer toutes les ressources qui ne sont pas nécessaires lorsque l'Activity n'est pas visible. Cela réduit la charge sur la batterie, le CPU et la mémoire, et empêche également les ANR lors du retour à l'activité.

Que libérer dans onStop :

  • Animations et transitions — arrêter ObjectAnimator, ValueAnimator, ViewPropertyAnimator. Les animations en cours sur une Activity invisible gaspillent des cycles GPU.
  • Capteurs — se désabonner de SensorManager (accéléromètre, gyroscope, magnétomètre). Les capteurs consomment de l'énergie même lorsque l'Activity est masquée.
  • Caméra et microphone — libérer Camera2 ou CameraX, arrêter MediaRecorder. Laisser la caméra active avec l'Activity masquée est interdit par la politique Google Play.
  • LocationListener — se désabonner de FusedLocationProviderClient ou LocationManager. La géolocalisation est la ressource la plus énergivore.
  • Écouteurs réseau — fermer WebSocket, annuler les requêtes HTTP qui ne sont pas nécessaires en arrière-plan.
  • MediaPlayer et ExoPlayer — mettre en pause ou arrêter la lecture si elle ne doit pas continuer en arrière-plan.

À ne pas faire dans onStop : N'effectuez pas d'opérations longues — sauvegarde de grandes quantités de données dans la base de données, requêtes réseau, calculs complexes. onStop s'exécute sur le thread principal et bloque le retour à l'Activity. Pour les opérations longues, utilisez WorkManager avec un délai ou des coroutines dans viewModelScope. Ne libérez pas les ressources de la ViewModel — la ViewModel survit à onStop et sera utilisée lors du retour.

Différence entre onStop et onPause

onPause et onStop diffèrent par le degré de perte de visibilité et l'étendue des actions obligatoires. onPause est appelé lors d'une perte partielle du focus (par exemple, ouverture d'une fenêtre de dialogue ou d'un menu système), onStop — lors d'une perte complète de visibilité. Cette différence est importante pour choisir quelles ressources libérer à chaque étape.

CaractéristiqueonPauseonStop
Niveau de visibilitéPartiellement visibleComplètement invisible
FocusPerduPerdu
Temps d'exécutionJusqu'à 500 msJusqu'à 5 s (timeout ANR)
Ressources à libérerCritiques (média, caméra)Toutes invisibles (capteurs, animations, localisation)
RestaurationonResumeonRestart → onStart → onResume
Priorité du processusÉlevée (Avant-plan)Moyenne (Arrière-plan)

Règle générale : dans onPause, libérez les ressources système qui affectent immédiatement l'expérience utilisateur d'une autre application (caméra, lecteur multimédia) ; dans onStop — toutes les autres ressources non nécessaires lorsque l'Activity est masquée. Google recommande de sauvegarder les données critiques de l'utilisateur (brouillon d'e-mail, paramètres) dans onPause, car onStop peut ne pas être appelé lors d'un changement rapide.

onStop → onRestart : retour à l'écran

Lorsque l'utilisateur revient à une Activity masquée, le système appelle onRestart → onStart → onResume. La méthode onRestart signale que l'Activity revient de l'état Stopped. C'est une étape importante pour restaurer l'interface et les ressources qui ont été libérées dans onStop.

Séquence d'appels lors du retour :

  • onRestart() — l'Activity est notifiée qu'elle sera affichée à nouveau. Actions typiques : rechargement des données, mise à jour des listes.
  • onStart() — l'Activity devient visible mais pas encore active. Ici, les ressources libérées dans onStop sont réinitialisées.
  • onResume() — l'Activity obtient le focus et est prête pour l'interaction. Les animations démarrent, les capteurs sont enregistrés.

Si le processus de l'application a été tué par le système à l'état Stopped, onCreate est appelé à la place de onRestart, et le Bundle de onSaveInstanceState est passé pour la restauration de l'état. Ce scénario (mort du processus) est l'une des causes les plus fréquentes de bugs dans les applications Android : les développeurs implémentent onRestart mais oublient de prendre en compte la restauration via onCreate après la mort du processus.

Exemples de code avec onStop en Kotlin

Exemple 1 : Implémentation de base de onStop avec libération des capteurs

Montre le désabonnement correct des capteurs et l'arrêt des animations lors du masquage de l'Activity. Au retour à l'écran, les ressources sont restaurées dans onStart.

kotlin
class MainActivity : AppCompatActivity() {
    private lateinit var sensorManager: SensorManager
    private var accelerometer: Sensor? = null
    private var rotationAnimator: ObjectAnimator? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
        accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
    }

    override fun onStart() {
        super.onStart()
        accelerometer?.let {
            sensorManager.registerListener(sensorListener, it, SensorManager.SENSOR_DELAY_NORMAL)
        }
        rotationAnimator = ObjectAnimator.ofFloat(findViewById(R.id.icon), "rotation", 0f, 360f)
        rotationAnimator?.apply {
            duration = 3000
            repeatMode = ValueAnimator.RESTART
            repeatCount = ValueAnimator.INFINITE
            start()
        }
    }

    override fun onStop() {
        super.onStop()
        sensorManager.unregisterListener(sensorListener)
        rotationAnimator?.cancel()
    }

    override fun onRestart() {
        super.onRestart()
        Log.d("MainActivity", "L'Activity revient de l'état Stopped")
    }

    private val sensorListener = SensorEventListener { event, _ ->
        Log.d("MainActivity", "Accél : x=${event.values[0]}, y=${event.values[1]}, z=${event.values[2]}")
    }
}

Le code enregistre le capteur d'accéléromètre et lance une animation de rotation infinie dans onStart. Dans onStop, le capteur est désenregistré et l'animation est annulée — cela évite la consommation de batterie lorsque l'Activity est masquée. Après le retour via onRestart → onStart, les ressources sont recréées.

Exemple 2 : onStop avec préservation de l'état via SavedStateHandle

Une approche moderne utilisant ViewModel + SavedStateHandle. Les données du formulaire sont automatiquement sauvegardées pendant onStop sans manipulation manuelle du Bundle.

kotlin
class FormViewModel(
    private val savedStateHandle: SavedStateHandle
) : ViewModel() {
    var email: String
        get() = savedStateHandle["email"] ?: ""
        set(value) { savedStateHandle["email"] = value }

    var message: String
        get() = savedStateHandle["message"] ?: ""
        set(value) { savedStateHandle["message"] = value }
}

class FormActivity : AppCompatActivity() {
    private val viewModel: FormViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_form)
        Log.d("FormActivity", "onCreate: email=${viewModel.email}")
    }

    override fun onStop() {
        super.onStop()
        Log.d("FormActivity", "onStop : données sauvegardées dans SavedStateHandle")
    }
}

SavedStateHandle sauvegarde automatiquement les valeurs dans le Bundle pendant onSaveInstanceState, qui est appelé avant onStop. Lors de la rotation de l'écran ou de la mort du processus, les données sont restaurées sans perte. Google recommande SavedStateHandle pour les formulaires et les brouillons plutôt que onSaveInstanceState direct.

Exemple 3 : lifecycleScope pour les opérations dans onStop

Utilisation de lifecycleScope avec des coroutines pour sauvegarder les données de manière asynchrone pendant la transition vers onStop. La coroutine s'exécute sur le dispatcher IO sans bloquer le thread principal.

kotlin
class NoteActivity : AppCompatActivity() {
    private val noteRepository = NoteRepository()

    override fun onStop() {
        lifecycleScope.launch(Dispatchers.IO) {
            val text = findViewById<EditText>(R.id.note_content).text.toString()
            noteRepository.saveDraft(text)
            withContext(Dispatchers.Main) {
                Log.d("NoteActivity", "Brouillon sauvegardé dans onStop")
            }
        }
        super.onStop()
    }
}

La coroutine lifecycleScope.launch est automatiquement annulée si le cycle de vie de l'Activity se termine. L'utilisation de Dispatchers.IO garantit que l'écriture dans la base de données ou le fichier ne bloque pas le retour à l'Activity. Selon Google, les coroutines dans lifecycleScope sont la méthode préférée pour effectuer des opérations asynchrones dans onStop.

Questions fréquentes

Quelle est la différence entre onStop et onDestroy ?

onStop — l'Activity cesse d'être visible mais reste en mémoire à l'état Stopped. Le système peut ramener l'Activity via onRestart. onDestroy — l'Activity est détruite, la mémoire est libérée. Après onDestroy, le retour n'est possible qu'en créant une nouvelle instance d'Activity (onCreate).

Est-il obligatoire d'appeler super.onStop() ?

Oui, obligatoire. super.onStop() garantit le fonctionnement correct des composants système : fragments, LoaderManager, ViewModelStore. Omettre super.onStop() peut provoquer des fuites de mémoire et une restauration incorrecte des fragments. Appelez toujours super.onStop() en dernier ou en premier — l'ordre n'est pas critique, mais l'appel est obligatoire.

Comment vérifier que onStop a été appelé ?

Utilisez Log.d ou Timber dans chaque méthode du cycle de vie. Activez le filtre logcat par le tag de votre Activity. Pour la production, utilisez Android Vitals — Google collecte automatiquement les métriques du cycle de vie et affiche les anomalies dans la Play Console. La surveillance du cycle de vie est également disponible via ProcessLifecycleOwner.

Que se passe-t-il si une exception est levée dans onStop ?

Une exception non capturée dans onStop provoque un Force Close de l'application. Le système n'attrape pas les exceptions dans les callbacks du cycle de vie. Si onStop effectue des opérations susceptibles de lever des exceptions (opérations sur fichiers, réseau), enveloppez-les dans un try-catch et enregistrez l'erreur sans interrompre super.onStop().

Faut-il libérer Bitmap dans onStop ?

Non, le Bitmap dans l'Activity sera collecté par le GC s'il n'y a pas de références vers lui. La libération forcée (recycle()) dans onStop n'est pas nécessaire et est même nuisible — si l'Activity revient via onRestart, le Bitmap devrait être rechargé. Utilisez Glide ou Coil pour le chargement des images — ces bibliothèques gèrent automatiquement le cache et le cycle de vie.

Résumé

  • onStop — méthode du cycle de vie de l'Activity appelée lors de la perte complète de visibilité. L'Activity reste en mémoire à l'état Stopped.
  • Après onStop, deux scénarios sont possibles : onRestart (retour à l'écran) ou onDestroy (destruction de l'Activity).
  • Dans onStop, vous devez libérer les capteurs, animations, caméra, écouteurs de localisation — tout ce qui n'est pas nécessaire lorsque l'Activity est invisible.
  • onStop diffère de onPause par le niveau de visibilité : onPause — perte partielle, onStop — perte complète de visibilité.
  • onSaveInstanceState est appelé avant onStop — utilisez-le pour sauvegarder l'état transitoire de l'interface.
  • Les coroutines de lifecycleScope avec Dispatchers.IO — la méthode préférée pour les opérations asynchrones dans onStop.
  • Appelez toujours super.onStop() et enveloppez les opérations dangereuses dans try-catch pour éviter le Force Close.

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi