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 — 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.
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 :
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 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).
| État | Méthode | Visibilité | Interaction | Mémoire |
|---|---|---|---|---|
| Created | onCreate | Non | Non | Allouée |
| Started | onStart | Partielle | Non | Complete |
| Resumed | onResume | Complete | Oui | Complete |
| Paused | onPause | Partielle | Non | Complete |
| Stopped | onStop | Non | Non | Complete* |
| Destroyed | onDestroy | Non | Non | Libé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.
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 :
À 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.
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éristique | onPause | onStop |
|---|---|---|
| Niveau de visibilité | Partiellement visible | Complètement invisible |
| Focus | Perdu | Perdu |
| Temps d'exécution | Jusqu'à 500 ms | Jusqu'à 5 s (timeout ANR) |
| Ressources à libérer | Critiques (média, caméra) | Toutes invisibles (capteurs, animations, localisation) |
| Restauration | onResume | onRestart → 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.
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 :
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.
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.
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.
Une approche moderne utilisant ViewModel + SavedStateHandle. Les données du formulaire sont automatiquement sauvegardées pendant onStop sans manipulation manuelle du Bundle.
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.
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.
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
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).
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.
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.
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().
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é
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.
Lisez aussi