L'Activity Lifecycle est un ensemble de méthodes de rappel qu'Android appelle lors de la transition d'une Activity entre différents états : création, visibilité, focus d'entrée, perte partielle de visibilité, masquage complet et destruction. Le système gère le cycle de vie de chaque écran de l'application, depuis l'appel de onCreate() jusqu'à onDestroy(). La compréhension de ces états est une exigence obligatoire pour le fonctionnement stable d'une application Android, car un traitement incorrect des transitions entre méthodes entraîne des fuites mémoire, une perte de données utilisateur et des crashs inattendus. En savoir plus sur l'architecture Android dans l'article général sur Android.
Points clés
L'Activity Lifecycle (cycle de vie d'une Activity) est une machine à états que chaque écran d'une application Android traverse depuis sa création jusqu'à sa destruction complète. Le système Android gère ce processus en fonction des actions de l'utilisateur : ouverture de l'application, minimisation, rotation de l'écran, réponse à un appel entrant, changement d'application et fermeture.
Comprendre le cycle de vie est essentiel pour tout développeur Android, car le système peut détruire une Activity à tout moment en cas de manque de mémoire — et l'application doit restaurer correctement son état. Selon Google Android Vitals (2025), les applications qui ne gèrent pas la sauvegarde d'état dans onSaveInstanceState() présentent 42 % de crashs supplémentaires lors de la recréation de l'Activity.
Le cycle de vie comprend six méthodes de rappel principales : onCreate(), onStart(), onResume(), onPause(), onStop(), onDestroy(). Il existe également la méthode onRestart(), appelée avant onStart() lorsqu'une Activity revient de l'état arrêté. Chaque méthode a un objectif et un temps d'exécution strictement définis — le système les appelle séquentiellement, et le développeur peut redéfinir n'importe laquelle pour implémenter sa propre logique.
Le cycle peut être divisé en trois étapes clés : durée de vie complète (onCreate → onDestroy), durée de vie visible (onStart → onStop) et durée de vie au premier plan (onResume → onPause). La compréhension de ces trois niveaux aide à répartir correctement le code d'initialisation et de libération des ressources.
Chaque méthode du cycle de vie effectue une tâche strictement définie. Le système les appelle dans un ordre fixe, et le développeur ne doit redéfinir que les méthodes nécessaires à la logique spécifique. Il n'est pas recommandé d'appeler directement les méthodes du cycle de vie — cela est géré par l'Android Runtime.
Une séquence typique au lancement de l'application : onCreate → onStart → onResume. En appuyant sur le bouton Retour : onPause → onStop → onDestroy. En minimisant : onPause → onStop, puis au retour : onRestart → onStart → onResume.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onStart() {
super.onStart()
}
override fun onResume() {
super.onResume()
}
override fun onPause() {
super.onPause()
}
override fun onStop() {
super.onStop()
}
override fun onDestroy() {
super.onDestroy()
}
override fun onRestart() {
super.onRestart()
}
}
Chaque méthode redéfinie doit appeler sa version super — sans cela, le système ne peut pas terminer correctement la transition d'état. Cette règle est établie dans la documentation Android Developers et est vérifiée par les règles lint d'Android Studio.
Premier niveau — durée de vie complète : l'intervalle entre onCreate et onDestroy. L'initialisation unique et la libération finale des ressources globales sont effectuées ici. Deuxième niveau — durée de vie visible : entre onStart et onStop. L'Activity est visible à l'écran mais peut être partiellement recouverte par une autre fenêtre. Troisième niveau — durée de vie au premier plan : entre onResume et onPause. L'Activity est au sommet de la pile de tâches et interagit avec l'utilisateur.
onCreate() — la première et unique méthode obligatoire du cycle de vie d'Activity. Elle est appelée par le système une fois lors de la création d'une instance d'Activity. Cette méthode accepte un paramètre savedInstanceState: Bundle?, qui contient l'état précédemment sauvegardé si l'Activity est recréée après destruction — par exemple, lors d'une rotation de l'écran.
À l'intérieur d'onCreate, les tâches suivantes sont effectuées : initialisation de l'interface utilisateur via setContentView() avec une ressource de layout, liaison des éléments View via findViewById(), configuration des adaptateurs pour RecyclerView et ViewPager, restauration de l'état depuis savedInstanceState, initialisation de ViewModel et LiveData, configuration des écouteurs de clic et de gestes. La méthode doit se terminer le plus rapidement possible — les opérations longues bloquent ici le rendu de la première image, augmentant le temps de démarrage de l'application.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_profile)
val userNameText: TextView = findViewById(R.id.user_name)
val loadButton: Button = findViewById(R.id.load_button)
if (savedInstanceState != null) {
userNameText.text = savedInstanceState.getString("user_name")
}
loadButton.setOnClickListener {
loadUserProfile()
}
}
Si l'Activity est créée pour la première fois, savedInstanceState est null. Lors de la recréation après une rotation d'écran, le Bundle contient les données sauvegardées dans onSaveInstanceState(). La vérification de null est une pratique standard pour restaurer correctement l'interface utilisateur sans perdre les données saisies par l'utilisateur.
onStart() est appelé immédiatement après onCreate() ou après onRestart(), lorsque l'Activity devient visible pour l'utilisateur. Dans cet état, l'Activity n'est pas encore au premier plan et ne peut pas interagir avec l'utilisateur, mais son interface utilisateur est déjà visible à l'écran. Par exemple, au lancement de l'application, le système rend la première image de l'interface entre les appels à onStart et onResume.
Dans la méthode onStart, les actions suivantes sont généralement effectuées : démarrage des animations qui doivent fonctionner tant que l'Activity est visible ; liaison des récepteurs de diffusion (BroadcastReceiver) ; connexion aux services de géolocalisation et aux capteurs ; mise à jour des données depuis ViewModel ou Room. La liaison aux services Bound via bindService() est également effectuée ici si l'application utilise une architecture client-serveur au sein du processus.
override fun onStart() {
super.onStart()
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
5000L,
10f,
locationListener
)
}
override fun onStop() {
super.onStop()
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
locationManager.removeUpdates(locationListener)
}
Règle importante : les ressources connectées dans onStart doivent être libérées dans onStop. Cela garantit que lorsque l'Activity n'est pas visible à l'écran, elle ne consomme pas de batterie ni de ressources système. Le Google Play Store vérifie les applications pour les fuites de LocationListener et d'autres services système lors de la modération des mises à jour.
onResume() — l'état dans lequel l'Activity est au premier plan et prête à interagir avec l'utilisateur. C'est l'état de travail de l'écran : le système transfère le focus d'entrée à l'Activity, et tous les événements tactiles, les saisies clavier et les gestes sont dirigés vers cet écran. La méthode onResume est appelée chaque fois que l'Activity revient au premier plan — après la fin d'une autre Activity, après la fermeture d'une boîte de dialogue, ou après le déverrouillage de l'appareil.
Dans onResume, les opérations suivantes sont effectuées : reprise des animations qui ont été mises en pause dans onPause ; ouverture de la caméra et d'autres ressources exclusives ; enregistrement des écouteurs de capteurs (accéléromètre, gyroscope) ; démarrage des minuteurs et du chronomètre pour l'interface utilisateur ; mise à jour du contenu de l'écran avec les données actuelles. La paire onResume/onPause est utilisée pour les ressources qui ne doivent être actives qu'en présence de focus — par exemple, la reconnaissance vocale continue ou la capture vidéo.
override fun onResume() {
super.onResume()
cameraHolder.openCamera()
animator.resume()
sensorManager.registerListener(
stepCounter,
sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER),
SensorManager.SENSOR_DELAY_NORMAL
)
}
override fun onPause() {
super.onPause()
cameraHolder.closeCamera()
animator.pause()
sensorManager.unregisterListener(stepCounter)
}
La différence entre onStart et onResume est significative : une Activity peut être visible (onStart) mais pas active (onResume) — par exemple, lorsqu'une boîte de dialogue contextuelle ou un écran de verrouillage transparent est affiché par-dessus. C'est dans onResume, et non dans onStart, que les ressources exclusives nécessitant un accès exclusif doivent être ouvertes.
onPause() est appelé lorsque l'Activity perd le focus d'entrée mais reste partiellement visible. Scénarios typiques : ouverture d'une boîte de dialogue, pression sur le bouton Applications récentes, appel entrant, pression sur le bouton Accueil (dans ce cas, onPause sera suivi de onStop). La méthode onPause est le dernier endroit fiable pour sauvegarder les données que l'utilisateur ne doit pas perdre.
Dans onPause, les opérations suivantes sont effectuées : sauvegarde des brouillons d'e-mails et des formulaires dans Room ou SharedPreferences ; arrêt des animations et de la lecture vidéo ; fermeture de la caméra et libération des ressources exclusives ; annulation des opérations coûteuses non critiques en arrière-plan. La méthode onPause doit se terminer en moins de 100 millisecondes — le système bloque la transition vers l'Activity suivante jusqu'à ce que onPause rende la main, et le dépassement de la limite entraîne un ANR (Application Not Responding).
override fun onPause() {
super.onPause()
val editor = SharedPreferences.Manager ...
editor.putString("draft_text", draftEditText.text.toString())
editor.apply()
videoView.pause()
cameraHolder.release()
}
Important : onPause s'exécute sur le thread de l'interface utilisateur, donc toute opération bloquante telle que l'écriture dans la base de données via Room avec une requête synchrone doit être remplacée par des opérations asynchrones (coroutines) ou exécutée sur un thread d'arrière-plan. Utilisez apply() au lieu de commit() pour SharedPreferences — apply écrit les données de manière asynchrone et ne bloque pas le thread de l'interface utilisateur.
onStop() est appelé lorsque l'Activity cesse d'être visible pour l'utilisateur. Cela se produit dans les cas suivants : l'Activity est complètement recouverte par une autre Activity ; l'utilisateur a appuyé sur le bouton Accueil ou est passé à une autre application ; l'Activity se termine (onDestroy sera appelé ensuite). Dans l'état onStop, l'Activity reste en mémoire et conserve tous ses champs — elle n'est ni détruite ni active.
Dans onStop, les opérations suivantes sont effectuées : désenregistrement des BroadcastReceiver enregistrés dans onStart ; déconnexion des services Bound ; libération de LocationListener, SensorListener et autres écouteurs système ; arrêt des opérations d'arrière-plan longues qui ne sont pas nécessaires lorsque l'application est masquée ; écriture de l'état actuel de l'interface utilisateur dans un Bundle via onSaveInstanceState() si cela n'a pas été fait dans onPause.
override fun onStop() {
super.onStop()
unregisterReceiver(connectivityReceiver)
unbindService(serviceConnection)
if (isChangingConfigurations()) {
Log.d("Lifecycle", "L'Activity est recréée en raison de la configuration")
}
}
Le système peut détruire une Activity dans l'état onStop sans appeler onDestroy en cas de manque de mémoire. Par conséquent, toutes les données critiques doivent être sauvegardées avant la transition vers onStop. Le drapeau isChangingConfigurations() permet de déterminer si l'appel à onStop est lié à une rotation de l'écran — dans ce cas, l'Activity sera recréée, et non terminée.
onDestroy() — la dernière méthode du cycle de vie appelée avant la destruction complète de l'Activity. Le système appelle onDestroy dans deux cas : l'Activity se termine via finish() ou l'utilisateur appuie sur le bouton Retour ; l'Activity est détruite par le système en raison d'un changement de configuration (par exemple, rotation de l'écran) et sera recréée. La méthode onDestroy permet d'effectuer le nettoyage final des ressources : désynchronisation des threads et des coroutines, fermeture des curseurs et des sockets ouverts en permanence, et libération de la mémoire native via le NDK.
override fun onDestroy() {
super.onDestroy()
backgroundJob.cancel()
dbHelper.close()
if (isFinishing) {
Log.d("Lifecycle", "L'Activity se termine définitivement")
} else {
Log.d("Lifecycle", "L'Activity sera recréée")
}
}
Remarque importante : onDestroy n'est pas garanti d'être appelé si le processus de l'application est tué par le système (out-of-memory kill). Par conséquent, on ne peut pas compter sur onDestroy pour sauvegarder les données — cette tâche est résolue dans onPause ou onStop. La propriété isFinishing permet de distinguer la fin de l'Activity via finish() de la recréation due à un changement de configuration.
onRestart() est appelé avant onStart() lorsqu'une Activity revient de l'état arrêté (onStop) au premier plan. Cela se produit lorsque l'utilisateur rouvre l'application depuis le menu Applications récentes ou revient à une Activity en appuyant sur Retour dans un écran enfant. La méthode onRestart permet d'exécuter une logique différente de celle d'onCreate — par exemple, mettre à jour les données qui ont pu changer pendant que l'Activity était masquée.
override fun onRestart() {
super.onRestart()
refreshDataFromNetwork()
Log.d("Lifecycle", "L'Activity redémarre depuis la pile")
}
Scénario typique : l'utilisateur a ouvert l'application, est passé à une autre tâche et est revenu une heure plus tard. Dans onRestart, l'application peut vérifier la pertinence des données et, si beaucoup de temps s'est écoulé, suggérer de recharger le contenu. Cela améliore l'expérience utilisateur et réduit la probabilité d'afficher des informations obsolètes.
La rotation de l'écran est le scénario le plus courant de recréation d'Activity. Par défaut, Android détruit l'Activity actuelle et en crée une nouvelle à chaque changement d'orientation. Si l'état n'est pas sauvegardé, l'utilisateur perd toutes les données saisies. Android fournit deux mécanismes pour cela : onSaveInstanceState() pour les données sérialisables et ViewModel pour les données qui survivent aux changements de configuration.
onSaveInstanceState() est appelé avant la destruction de l'Activity pour sauvegarder l'état temporaire. Les données sauvegardées sont passées à onCreate via le paramètre savedInstanceState et à la méthode onRestoreInstanceState(), qui est appelée après onStart. Le Bundle a une limite de taille — environ 500 Ko, donc les gros volumes de données (par exemple, les bitmaps) sont sauvegardés via ViewModel.
<!-- AndroidManifest.xml — verrouillage de l'orientation -->
<activity android:name=".MainActivity"
android:configChanges="orientation|screenSize" />
Le verrouillage de l'orientation via android:configChanges empêche la recréation de l'Activity, mais est considéré comme un anti-patron si l'application doit prendre en charge les deux orientations. La recommandation moderne de Google est d'utiliser ViewModel en combinaison avec onSaveInstanceState pour les données que l'utilisateur saisit dans l'interface utilisateur.
Fragment a son propre cycle de vie, similaire à celui d'Activity, mais avec des méthodes supplémentaires : onAttach, onCreate, onCreateView, onViewCreated, onStart, onResume, onPause, onStop, onDestroyView, onDestroy, onDetach. Un Fragment existe toujours au sein d'une Activity, et son cycle de vie est lié à celui de l'Activity conteneur. Si l'Activity est détruite, le Fragment la suit.
La principale différence : Fragment gère non seulement l'état du composant, mais aussi la hiérarchie des vues. La méthode onCreateView retourne la vue racine du Fragment, et onDestroyView détruit cette hiérarchie. Cela permet au Fragment de survivre à la recréation de l'Activity lors de la rotation de l'écran : le Fragment est conservé et sa vue est recréée dans onCreateView.
class ProfileFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return inflater.inflate(R.layout.fragment_profile, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val avatarImage: ImageView = view.findViewById(R.id.avatar_image)
loadAvatar(avatarImage)
}
}
Comprendre la différence entre onCreate et onCreateView est crucial : onCreate est appelé une fois par vie du Fragment (même lorsque la vue est recréée), tandis qu'onCreateView est appelé à chaque fois que le Fragment crée ou recrée sa hiérarchie de vues. L'initialisation des données est effectuée dans onCreate, tandis que la liaison de l'interface utilisateur est effectuée dans onViewCreated.
LifecycleObserver — un composant de la bibliothèque Android Jetpack qui permet de réagir aux changements du cycle de vie sans redéfinir les méthodes dans Activity ou Fragment. Au lieu de dupliquer le code dans chaque méthode du cycle de vie, le développeur crée une classe séparée avec des annotations @OnLifecycleEvent et la passe à lifecycle.addObserver().
Jetpack fournit également l'interface LifecycleOwner, qui est implémentée par AppCompatActivity et Fragment. Tout objet implémentant LifecycleOwner peut gérer les abonnements LiveData, les coroutines via lifecycleScope et WorkManager en relation avec le cycle de vie. C'est une pierre angulaire de l'architecture Android moderne basée sur MVVM et Jetpack.
class MyLocationObserver(private val context: Context) : DefaultLifecycleObserver {
override fun onStart(owner: LifecycleOwner) {
startLocationUpdates()
}
override fun onStop(owner: LifecycleOwner) {
stopLocationUpdates()
}
}
// Dans Activity :
lifecycle.addObserver(MyLocationObserver(this))
L'utilisation de DefaultLifecycleObserver simplifie les tests, réduit la duplication de code et rend la logique du cycle de vie réutilisable entre différents écrans. C'est un remplacement moderne de la redéfinition manuelle de onStart/onStop dans chaque Activity. Dans les applications Android développées par IT Sectr, nous appliquons LifecycleObserver pour la géolocalisation, le scan Bluetooth et l'analytique — cela réduit le volume de code passe-partout de 30 à 40 %.
Questions fréquentes
Si vous n'appelez pas super.onCreate() ou toute autre méthode super du cycle de vie, le système lancera une exception SuperNotCalledException et l'application plantera. C'est une exigence stricte de l'Android Runtime — chaque méthode doit déléguer l'exécution à la classe de base, sinon la machine à états interne ne peut pas passer à l'état suivant.
L'Activity est recréée lors de la rotation de l'écran parce que le changement d'orientation est un changement de configuration de l'appareil. Par défaut, Android détruit l'Activity et en crée une nouvelle pour charger des ressources alternatives (layout-land, values-land). Pour désactiver la recréation, vous pouvez ajouter l'attribut android:configChanges dans le manifeste, mais Google recommande d'utiliser ViewModel pour préserver les données.
Les données critiques sont sauvegardées dans onPause(), car c'est la dernière méthode garantie d'être appelée avant que l'application ne soit tuée par le système. Après onStop et onDestroy, le système peut terminer le processus sans appeler de méthodes supplémentaires. Pour les brouillons et les données intermédiaires, utilisez SharedPreferences avec apply() ou Room avec des coroutines.
onPause est appelé lorsque l'Activity perd le focus mais reste partiellement visible (par exemple, une boîte de dialogue est ouverte). onStop est appelé lorsque l'Activity est complètement masquée de l'écran par une autre Activity ou en appuyant sur le bouton Accueil. La principale différence pratique : onPause est le dernier point pour sauvegarder les données, onStop est l'endroit pour libérer les écouteurs et les services système qui ne sont pas nécessaires en arrière-plan.
ViewModel est un composant Android Jetpack qui stocke les données de l'interface utilisateur et survit automatiquement aux changements de configuration (rotation de l'écran). ViewModel n'est pas détruit lors de la recréation de l'Activity : il vit jusqu'à ce que le LifecycleOwner (Activity ou Fragment) soit complètement terminé. Cela résout le problème de conservation des données lors de la rotation de l'écran sans utiliser Bundle ni onSaveInstanceState. ViewModel est un élément obligatoire de l'architecture MVVM recommandée par Google.
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