onResume est une méthode du cycle de vie Android qui est appelée lorsqu'une Activity ou un Fragment passe au premier plan et reçoit le focus d'entrée. Dans cet état, l'écran est prêt pour l'interaction avec l'utilisateur : tous les événements tactiles, pressions de touches et gestes sont dirigés vers ce composant. onResume est l'état de travail d'une Activity, où l'application passe la majeure partie de son temps. C'est ici que l'on ouvre la caméra, que l'on démarre la lecture vidéo, que l'on commence la reconnaissance vocale et que l'on enregistre les écouteurs de capteurs nécessitant un accès exclusif. Pour plus d'informations sur le cycle de vie complet d'une Activity, lisez l'article Activity Lifecycle.
Points clés
onResume — la troisième méthode du cycle de vie d'une Activity, appelée après onStart, qui signale que l'écran est prêt pour une interaction complète avec l'utilisateur. À ce moment, l'Activity est au sommet de la pile des tâches (back stack), le système lui dirige tous les événements d'entrée, et l'application peut démarrer toute opération nécessitant la participation active de l'utilisateur : appels vidéo, jeux, enregistrement audio, dessin sur Canvas.
onResume fait partie de la « durée de vie au premier plan » (foreground lifetime) — l'intervalle entre onResume et onPause. C'est la période la plus active d'une Activity, lorsque l'application consomme le plus de ressources : CPU pour le traitement tactile, GPU pour le rendu des animations, caméra et microphone pour la capture vidéo. Comprendre ce niveau du cycle de vie est essentiel pour optimiser la consommation d'énergie — les ressources ouvertes dans onResume doivent être immédiatement fermées dans onPause.
Selon Google I/O 2025, le temps moyen qu'une Activity passe dans l'état onResume par session est de 2 à 5 minutes pour les applications d'actualités et de 15 à 30 minutes pour les jeux et les messageries. Tout le reste du temps, l'Activity est dans les états onPause, onStop ou onDestroy. Cela signifie que l'optimisation spécifique du code onResume offre les plus grands gains en performances et en autonomie de la batterie.
Dans une Activity, la méthode onResume est appelée chaque fois que l'écran reçoit le focus d'entrée — au premier lancement, lors du retour d'une autre Activity, à la fermeture d'une boîte de dialogue, au déverrouillage de l'appareil. C'est une méthode « chaude » qui peut être appelée plusieurs fois par session, et son implémentation doit être aussi légère que possible.
class CameraActivity : AppCompatActivity() {
private var cameraProvider: ProcessCameraProvider? = null
private var preview: Preview? = null
override fun onResume() {
super.onResume()
val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
cameraProviderFuture.addListener({
cameraProvider = cameraProviderFuture.get()
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
preview = Preview.Builder().build().also {
it.setSurfaceProvider(binding?.viewFinder?.surfaceProvider)
}
try {
cameraProvider?.unbindAll()
cameraProvider?.bindToLifecycle(
this, cameraSelector, preview
)
} catch (e: Exception) {
Log.e("Camera", "Failed to bind camera", e)
}
}, ContextCompact.getMainExecutor(this))
}
override fun onPause() {
super.onPause()
cameraProvider?.unbindAll()
preview = null
}
}
L'exemple avec CameraX illustre l'utilisation classique de onResume/onPause : la caméra est une ressource exclusive qui ne peut être utilisée que par une seule application à la fois. Lier la caméra au cycle de vie via bindToLifecycle ferme automatiquement la caméra dans onPause, mais un appel explicite à unbindAll garantit une libération immédiate. Ceci est particulièrement important lors du changement entre Activities : la caméra doit être libérée avant qu'une autre Activity tente de l'ouvrir.
onResume dans un Fragment est appelé après que l'Activity qui le contient a reçu onResume. Cependant, en raison des spécificités de FragmentManager et ViewPager, le moment de l'appel onResume pour un Fragment peut être retardé par rapport à l'Activity. Par exemple, un Fragment dans un ViewPager avec offscreenPageLimit = 1 reçoit onResume uniquement lorsqu'il devient la page courante, pas au démarrage de l'Activity.
class VideoPlayerFragment : Fragment() {
private var exoPlayer: ExoPlayer? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
exoPlayer = ExoPlayer.Builder(requireContext()).build()
binding?.playerView?.player = exoPlayer
}
override fun onResume() {
super.onResume()
exoPlayer?.play()
if (userVisibleHint) {
startBiometricAuth()
}
}
override fun onPause() {
exoPlayer?.pause()
stopBiometricAuth()
super.onPause()
}
}
La vérification de userVisibleHint dans Fragment.onResume est pertinente pour ViewPager : un Fragment peut recevoir onResume mais être masqué par une page voisine (par exemple, lors d'une transition animée). Dans de tels cas, démarrer une vidéo ou une biométrie dans onResume sans vérifier la visibilité entraînera un comportement inattendu. À partir de Fragment 1.5.0, il est recommandé d'utiliser FragmentTransaction.setMaxLifecycle() pour un contrôle précis du cycle de vie des fragments dans ViewPager2.
Les développeurs confondent souvent onStart et onResume, plaçant le code dans la mauvaise méthode. La règle principale : onStart — pour les ressources qui fonctionnent pendant la visibilité ; onResume — pour les ressources qui nécessitent le focus d'entrée. Examinons des scénarios spécifiques et le choix correct de la méthode.
| Opération | Méthode | Justification |
|---|---|---|
| Abonnement à la géolocalisation | onStart / onStop | Le GPS peut fonctionner avec une visibilité partielle |
| Ouverture de la caméra | onResume / onPause | La caméra est une ressource exclusive |
| BroadcastReceiver | onStart / onStop | Les événements système ne nécessitent pas de focus |
| Lecture vidéo | onResume / onPause | La vidéo doit être visible pour l'utilisateur |
| Scan Bluetooth | onStart / onStop | Le scan peut s'exécuter en arrière-plan |
| Enregistreur vocal (MediaRecorder) | onResume / onPause | L'enregistrement nécessite une UI active |
| Écouteurs de capteurs | onResume / onPause | Capteurs pour jeux et gestes |
| Mise à jour des données | onStart | Données fraîches nécessaires à l'apparition |
Une règle pratique : si une opération doit être interrompue lorsqu'une boîte de dialogue apparaît — utilisez onResume/onPause. Si une opération peut continuer lorsque l'écran est partiellement couvert — utilisez onStart/onStop. Par exemple, un lecteur vidéo doit mettre la vidéo en pause lors de l'ouverture d'une boîte de dialogue (onPause), tandis que la géolocalisation peut continuer à se mettre à jour (reste dans onStart).
Les ressources exclusives sont des composants de l'appareil qui ne peuvent être utilisés que par une seule application à un moment donné. Caméra, microphone, sortie vidéo (MediaProjection), adaptateur NFC en mode lecture, périphériques USB en mode accessoire — toutes ces ressources doivent être ouvertes dans onResume et libérées dans onPause.
MediaRecorder est utilisé pour enregistrer l'audio et la vidéo. Les demandes d'autorisation et la préparation de MediaRecorder sont effectuées dans onCreate, tandis que l'enregistrement commence dans onResume. Si l'utilisateur passe à une autre application, onPause met l'enregistrement en pause et onResume le reprend. C'est le comportement standard pour les dictaphones et les applications d'enregistrement vidéo.
private var mediaRecorder: MediaRecorder? = null
private var isRecording = false
override fun onResume() {
super.onResume()
if (isRecording) {
mediaRecorder?.resume()
}
}
override fun onPause() {
if (isRecording) {
mediaRecorder?.pause()
}
super.onPause()
}
L'authentification biométrique (BiometricPrompt) ne doit être appelée que lorsque l'Activity est dans onResume. Si elle est appelée dans onCreate ou onStart, la boîte de dialogue biométrique peut apparaître avant que l'Activity ait terminé son initialisation, ce qui entraîne un traitement incorrect du résultat. L'appeler dans onResume garantit que la fenêtre biométrique s'affiche dans le contexte correct.
Examinons trois modèles éprouvés pour travailler avec onResume utilisés dans des projets commerciaux : réinitialisation du minuteur d'inactivité, mise à jour des données visibles et intégration avec Jetpack Navigation.
Dans les applications avec des données sensibles (banque, dossiers médicaux), onResume est utilisé pour réinitialiser le minuteur de déconnexion automatique. Si l'utilisateur interagit activement avec l'application, onResume est appelé à chaque transition d'écran et le minuteur se réinitialise. Si l'utilisateur minimise l'application, onPause arrête le minuteur, et onResume au retour soit le réinitialise, soit demande une réauthentification.
Une liste qui doit afficher des données à jour chaque fois que l'on revient sur l'écran est mise à jour dans onResume. Par exemple, si l'utilisateur a créé une nouvelle entrée dans une autre Activity et est revenu en arrière, onResume recharge la liste depuis la base de données locale ou le cache ViewModel. Cela garantit la cohérence des données sans appel manuel à notifyDataSetChanged.
override fun onResume() {
super.onResume()
// ActivityResultLauncher a retourné un résultat — mise à jour de la liste
viewModel.refreshList()
// Réinitialisation du minuteur d'inactivité
inactivityTimer.reset()
}
Dans Jetpack Navigation, onResume d'un fragment est appelé chaque fois que vous y revenez via la navigation arrière. Cette propriété est utilisée pour réinitialiser l'état de l'UI : masquer le clavier, effacer les champs de recherche, mettre à jour le titre de la barre d'outils. OnBackPressedCallback combiné avec onResume donne un contrôle total sur la navigation sans duplication de code.
Questions fréquentes
onStart — l'écran est visible. onResume — l'écran est actif et prêt à interagir. Imaginez : vous regardez la télévision (onStart), mais vous prenez la télécommande (onResume). La télévision est toujours visible, mais l'interaction ne commence qu'avec la télécommande. Si quelqu'un couvre la télévision avec un rideau — l'écran cesse d'être visible (onStop). Si quelqu'un vous prend la télécommande — l'interaction cesse (onPause), mais la télévision est toujours visible.
onResume est appelé chaque fois que l'Activity reçoit le focus d'entrée. Le minimum est une fois (au lancement). Le maximum dépend des scénarios d'utilisation : changement d'écrans, ouverture de boîtes de dialogue, verrouillage et déverrouillage rapide de l'appareil — chacun de ces scénarios appelle onResume lors du retour à l'écran.
La caméra est une ressource exclusive disponible pour une seule application à la fois. Si vous ouvrez la caméra dans onCreate ou onStart, elle restera verrouillée pour les autres applications même lorsque votre application est inactive. onResume garantit que la caméra n'est ouverte que lorsque l'Activity est au premier plan, et onPause la ferme immédiatement. C'est une norme de développement Android, établie dans la documentation de CameraX et Camera2 API.
Oui, onResume peut ne pas se produire si une Activity est recouverte par une autre Activity immédiatement après son apparition. Par exemple, l'Activity A démarre l'Activity B dans la méthode onCreate ou onStart. Dans ce cas, A reçoit onStart → onPause → onStop, en sautant onResume. Le système n'appelle pas onResume parce que l'Activity A n'a jamais reçu le focus d'entrée.
Dans onResume, il ne faut pas effectuer d'opérations synchrones longues : chargement de grandes données depuis le réseau, requêtes SQL complexes, traitement d'images. onResume s'exécute dans le thread UI, et tout blocage de plus de 100 à 200 ms entraîne un retard de réactivité de l'interface. Toutes les opérations lourdes doivent être asynchrones — via les coroutines, RxJava ou WorkManager. Il est également déconseillé d'appeler finish() dans onResume sans vérification — cela peut entraîner une boucle infinie de recréation.
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