App Lifecycle : qu'est-ce que c'est, états de l'application sous iOS et Android

Auteur : IT Sectr Publié le : 2026-03-02 Temps de lecture : 8 min
App Lifecycle (cycle de vie d'une application) est la séquence d'états par lesquels une application mobile passe du lancement à la terminaison. Comprendre le cycle de vie est essentiel pour la gestion des ressources, la persistance des données et la garantie de stabilité. Sous iOS, l'application passe par les états : Not Running → Active → Inactive → Background → Suspended. Sous Android — via onCreate → onStart → onResume → onPause → onStop → onDestroy + onRestart. Chaque état donne au développeur une fenêtre pour sauvegarder l'état, libérer des ressources ou se préparer au retour. Selon la Documentation Apple, ignorer les événements du cycle de vie est la cause de 40 % des crashs lors de la minimisation d'une application. Chez IT Sectr, nous avons implémenté ProcessLifecycleOwner sous Android et le modèle AppDelegate sous iOS comme standards obligatoires pour tous les projets — cela a réduit les bogues liés à l'arrière-plan de 60 %.

Points clés

  • App Lifecycle — ensemble d'états de l'application du lancement à la terminaison, chacun avec des actions spécifiques du développeur.
  • AppDelegate — la classe centrale iOS pour le traitement du cycle de vie : didFinishLaunching, didEnterBackground, willEnterForeground.
  • SceneDelegate — délégué pour les scènes individuelles (iOS 13+), gérant le cycle de vie de chaque fenêtre dans les applications multi-fenêtres.
  • ProcessLifecycleOwner — composant Android d'AndroidX Lifecycle qui suit le cycle de vie de l'ensemble du processus.
  • Application.onCreate — le premier point d'entrée d'une application Android, appelé avant toute Activity.

Qu'est-ce qu'App Lifecycle ?

App Lifecycle est une machine à états finis qui décrit tous les états possibles d'une application mobile et les transitions entre eux. Chaque état détermine si l'application peut exécuter du code, afficher l'interface utilisateur et consommer des ressources. iOS et Android ont des modèles similaires mais non identiques — les différences proviennent de l'architecture du système d'exploitation : iOS utilise un contrôle strict de la mémoire (état suspended), tandis qu'Android utilise une gestion flexible des processus via onSaveInstanceState.

Sous iOS, le cycle de vie est étroitement lié au premier plan/arrière-plan : l'application est soit active, soit suspendue. Sous Android, le cycle de vie est plus granulaire — une Activity/Fenêtre passe par 6+ états, et le processus lui-même a un cycle de vie supplémentaire via ProcessLifecycleOwner. Les applications modernes (depuis 2024) utilisent de plus en plus des modèles d'architecture basés sur le cycle de vie : SwiftUI Lifecycle (iOS 16+) via l'environnement .scenePhase, Compose Lifecycle via LifecycleEventObserver. Ces modèles gèrent automatiquement les changements de contexte et préviennent les fuites mémoire. Selon Google, la gestion correcte du cycle de vie sous Android réduit la consommation mémoire de 30 à 40 % lors du travail en arrière-plan.

Cycle de vie iOS : AppDelegate et SceneDelegate

Sous iOS, le cycle de vie de l'application est géré via la classe UIApplicationDelegate (AppDelegate). Les principales méthodes : application(_:didFinishLaunchingWithOptions:) — initialisation au premier lancement ; applicationDidBecomeActive — l'application est visible et prête à interagir ; applicationWillResignActive — transition vers l'état inactif (appel entrant, fermeture du panneau de notifications) ; applicationDidEnterBackground — l'application est cachée, ~5 secondes pour sauvegarder les données ; applicationWillEnterForeground — retour de l'arrière-plan ; applicationWillTerminate — terminaison (appelée uniquement pour les anciennes applications sans suspended).

À partir d'iOS 13, Apple a introduit SceneDelegate (UISceneDelegate) pour prendre en charge les applications multi-fenêtres sur iPad et macOS Catalyst. SceneDelegate gère le cycle de vie de chaque scène (fenêtre) individuelle : scene(_:willConnectTo:options:) — création de la scène ; sceneDidBecomeActive — scène active ; sceneWillResignActive — scène perd le focus ; sceneDidEnterBackground — scène cachée. AppDelegate gère les événements globaux (chargement de données, notifications push), tandis que SceneDelegate gère l'état de l'interface utilisateur de chaque fenêtre. Dans SwiftUI, le cycle de vie est géré via la valeur d'environnement @Environment(\.scenePhase) : .active, .inactive, .background — cela fournit une API unifiée pour les applications SwiftUI et UIKit.

Cycle de vie Android : Application et ProcessLifecycleOwner

Sous Android, le cycle de vie commence avec la classe Application — un singleton créé avant toute Activity. La méthode Application.onCreate() est le premier point d'entrée, utilisée pour l'initialisation globale (Analytics, DI, Crash Reporting). Ensuite, l'Activity est lancée avec la séquence : onCreate() → onStart() → onResume(). Lors de la minimisation : onPause() → onStop() → onSaveInstanceState(). Lors de la destruction : onDestroy(). Au retour : onRestart() → onStart() → onResume().

ProcessLifecycleOwner (d'AndroidX Lifecycle 2.2+) suit le cycle de vie de l'ensemble du processus, pas d'une Activity individuelle. Il fournit deux états : ON_RESUME (application au premier plan) et ON_STOP (application cachée). ProcessLifecycleOwner résout le problème du « quand l'application est passée en arrière-plan » au niveau du processus — c'est essentiel pour les SDK, bibliothèques et applications modulaires. Dans Jetpack Compose, le cycle de vie est géré via LifecycleEventObserver et collectAsStateWithLifecycle, qui suspend automatiquement la collecte de données en mode arrière-plan. Android 14 (API 34) a ajouté une notification de cycle de vie du service de premier plan via Service.onTimeout — le service doit se terminer dans les 6 heures, sinon le système l'arrête de force.

Comparaison du cycle de vie iOS et Android

iOS Android Description
Not Running L'application n'est pas lancée
didFinishLaunching Application.onCreate Première initialisation au lancement
Active onResume L'application est visible et accepte les entrées
Inactive onPause Perte temporaire du focus (appel, panneau de notifications)
Background onStop L'application est cachée, le code peut s'exécuter
Suspended Le code ne s'exécute pas, la mémoire est réservée
Will Terminate onDestroy L'application se termine

La principale différence : iOS force la transition de l'application vers Suspended (le code cesse de s'exécuter) 5 à 10 secondes après son entrée en arrière-plan. Android permet le travail en arrière-plan (services, WorkManager) pendant une période plus longue, mais avec les limitations du mode Doze (Android 6+) et des restrictions d'arrière-plan (Android 12+). ProcessLifecycleOwner sous Android est l'équivalent de UIApplicationDidEnterBackgroundNotification sous iOS, à la différence près qu'il se déclenche lors de toute transition vers l'arrière-plan, pas seulement après une perte de focus.

Exemples de code

iOS : AppDelegate avec méthodes de cycle de vie

Implémentation de base d'AppDelegate gérant tous les états du cycle de vie. Sauvegarde des données lors du passage en arrière-plan et mise à jour de l'interface utilisateur au retour.

swift
import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        Analytics.shared.initialize()
        return true
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        NotificationCenter.default.post(name: .appDidBecomeActive, object: nil)
    }

    func applicationWillResignActive(_ application: UIApplication) {
        NotificationCenter.default.post(name: .appWillResignActive, object: nil)
    }

    func applicationDidEnterBackground(_ application: UIApplication) {
        CoreDataManager.shared.saveContext()
        UserDefaults.standard.synchronize()
    }

    func applicationWillEnterForeground(_ application: UIApplication) {
        NetworkManager.shared.refreshSession()
    }
}

AppDelegate est le point central du cycle de vie. applicationDidEnterBackground est une méthode critique : iOS donne ~5 secondes pour sauvegarder. applicationDidBecomeActive — mettez à jour l'interface utilisateur, redémarrez les animations. Pour SceneDelegate (iOS 13+), la logique du cycle de vie est répartie entre les scènes : sceneDidBecomeActive / sceneDidEnterBackground gèrent les fenêtres individuelles.

iOS : SceneDelegate (iOS 13+)

SceneDelegate pour les applications iPad multi-fenêtres. Chaque scène a son propre cycle de vie, indépendant des autres fenêtres.

swift
import UIKit

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    func scene(
        _ scene: UIScene,
        willConnectTo session: UISceneSession,
        options connectionOptions: UIScene.ConnectionOptions
    ) {
        guard let windowScene = (scene as? UIWindowScene) else { return }
        window = UIWindow(windowScene: windowScene)
        window?.rootViewController = ViewController()
        window?.makeKeyAndVisible()
    }

    func sceneDidBecomeActive(_ scene: UIScene) {
        PlayerManager.shared.resume()
    }

    func sceneDidEnterBackground(_ scene: UIScene) {
        PlayerManager.shared.pause()
        CoreDataManager.shared.saveContext()
    }

    func sceneDidDisconnect(_ scene: UIScene) {
        PlayerManager.shared.cleanup()
    }
}

SceneDelegate gère le cycle de vie d'une scène individuelle. sceneDidBecomeActive / sceneDidEnterBackground sont les équivalents des méthodes AppDelegate pour une fenêtre spécifique. sceneDidDisconnect est appelé lorsqu'une scène se ferme (l'utilisateur a fermé une fenêtre sur iPad). Pour la compatibilité avec iOS 12 et versions antérieures, AppDelegate doit dupliquer la logique de SceneDelegate. Sous iOS 17+, vous pouvez utiliser @Observable pour suspendre/reprendre automatiquement les tâches en fonction de scenePhase.

Android : Application avec ProcessLifecycleOwner

ProcessLifecycleOwner suit quand l'application est au premier plan/arrière-plan au niveau du processus. C'est l'approche optimale pour la gestion globale du cycle de vie.

kotlin
import android.app.Application
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent

class MainApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        ProcessLifecycleOwner.get().lifecycle.addObserver(AppLifecycleObserver())
    }
}

class AppLifecycleObserver : LifecycleObserver {

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun onEnterForeground() {
        Analytics.shared.onForeground()
        NetworkMonitor.shared.start()
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun onEnterBackground() {
        Analytics.shared.onBackground()
        NetworkMonitor.shared.stop()
    }
}

ProcessLifecycleOwner est la seule façon correcte de suivre la transition vers l'arrière-plan au niveau de l'application. ON_START se déclenche lorsque l'application devient visible (premier plan), ON_STOP — lorsqu'elle est complètement cachée (arrière-plan). Contrairement au cycle de vie d'Activity, ProcessLifecycleOwner n'est pas lié à un écran spécifique. Pour Jetpack Compose, utilisez LifecycleResumeEffect ou collectAsStateWithLifecycle au lieu d'une observation manuelle.

Android : Cycle de vie d'Activity avec ViewModel

ViewModel + Lifecycle est l'architecture Android correcte pour la gestion du cycle de vie. ViewModel est automatiquement nettoyé lors d'onDestroy, empêchant les fuites.

kotlin
import androidx.lifecycle.ViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData

class TimerViewModel : ViewModel() {

    private val _time = MutableLiveData<Long>()
    val time: LiveData<Long> = _time

    private var startTime = System.currentTimeMillis()

    init {
        updateTime()
    }

    private fun updateTime() {
        _time.value = System.currentTimeMillis() - startTime
    }

    override fun onCleared() {
        super.onCleared()
        Logger.d("ViewModel cleared — libération des ressources")
    }
}

// Dans Activity
class TimerActivity : AppCompatActivity() {

    private val viewModel: TimerViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Logger.d("Activity created")
    }

    override fun onResume() {
        super.onResume()
        viewModel.time.observe(this) { Logger.d("Time: $it") }
    }

    override fun onPause() {
        super.onPause()
        Logger.d("Activity paused — pause des animations")
    }

    override fun onDestroy() {
        super.onDestroy()
        Logger.d("Activity destroyed — nettoyage")
    }
}

ViewModel survit à la rotation de l'écran et n'est détruit qu'à la fin de l'Activity. onCleared() est l'endroit pour libérer les ressources et se désabonner des flux. LiveData suspend automatiquement l'observation lors d'onPause et la reprend lors d'onResume — cela offre une protection contre les fuites et les crashs pendant le travail en arrière-plan. Dans Compose, utilisez collectAsStateWithLifecycle() dans le même but.

Foire aux questions

Que se passe-t-il lorsqu'un utilisateur minimise une application iOS ?

Lors de la minimisation, l'application passe de l'état actif à inactif (brièvement), puis à l'arrière-plan. Après quelques secondes, le système peut la déplacer en suspended — le code cesse de s'exécuter, la mémoire est réservée. Lorsque la mémoire est insuffisante, le système termine l'application suspendue (willTerminate n'est pas appelé). Sauvegardez vos données dans applicationDidEnterBackground — c'est le dernier point garanti pour la sauvegarde.

Dois-je gérer tous les états d'App Lifecycle ?

Minimum obligatoire : applicationDidEnterBackground — sauvegarder les données utilisateur ; applicationWillEnterForeground — mettre à jour l'interface utilisateur ; sous Android onPause — mettre en pause les animations/capteurs. ProcessLifecycleOwner simplifie la gestion : onResume — onPause pour le premier plan, onStart — onStop pour la visibilité. Gérez les autres états selon les besoins — tous les états ne sont pas critiques pour chaque application.

En quoi SceneDelegate diffère d'AppDelegate ?

AppDelegate est le délégué global de l'ensemble de l'application (lancement, transition vers l'arrière-plan). SceneDelegate (iOS 13+) gère le cycle de vie d'une fenêtre individuelle (scène) — dans les applications iPad multi-fenêtres, chaque scène a son propre cycle de vie. Pour iOS 12 et versions antérieures, tout le cycle de vie est géré via AppDelegate. Avec iPadOS 16+, SceneDelegate est obligatoire pour Stage Manager.

Qu'est-ce que ProcessLifecycleOwner sous Android ?

ProcessLifecycleOwner est un composant d'AndroidX Lifecycle qui suit le cycle de vie de l'ensemble de l'application (processus), pas d'une Activity individuelle. Il fournit deux événements principaux : ON_RESUME (application au premier plan) et ON_STOP (application en arrière-plan). Il est utilisé pour l'initialisation/le nettoyage des SDK, analyses, moniteurs réseau — tout ce qui doit réagir au passage de l'application en arrière-plan, indépendamment de l'écran actuel.

Comment gérer le cycle de vie dans Jetpack Compose ?

Dans Jetpack Compose, utilisez LifecycleEventObserver via LocalLifecycleOwner.current.lifecycle ou la fonction collectAsStateWithLifecycle(). Pour les écrans Compose, utilisez LifecycleResumeEffect — similaire à DisposableEffect, qui s'exécute lors d'onResume et se nettoie lors d'onPause. lifecycleScope.launchWhenResumed — une coroutine qui se suspend automatiquement en arrière-plan.

Résumé

  • App Lifecycle est une machine à états finis qui détermine la gestion des ressources, la persistance des données et la stabilité.
  • iOS AppDelegate (applicationDidEnterBackground) est la méthode critique pour sauvegarder les données lors du passage en arrière-plan en 5 secondes.
  • iOS SceneDelegate (iOS 13+) gère le cycle de vie de chaque scène séparément — obligatoire pour les applications iPad multi-fenêtres.
  • Android ProcessLifecycleOwner est un observateur global du cycle de vie du processus pour l'initialisation/le nettoyage des SDK.
  • ViewModel sous Android survit à la rotation de l'écran et est nettoyé à la fin de l'Activity — empêche les fuites mémoire.
  • SwiftUI @Environment(\.scenePhase) fournit une API unifiée pour le cycle de vie dans SwiftUI (active, inactive, background).
  • La gestion correcte du cycle de vie réduit la consommation mémoire de 30 à 40 % et prévient 40 % des crashs lors du travail en arrière-plan.

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