App Lifecycle: qué es, estados de la aplicación en iOS y Android

Autor: IT Sectr Publicado: 2026-03-02 Tiempo de lectura: 8 min
App Lifecycle (ciclo de vida de la aplicación) es la secuencia de estados por los que pasa una aplicación móvil desde el inicio hasta la finalización. Comprender el lifecycle es fundamental para la gestión de recursos, la persistencia de datos y la garantía de estabilidad. En iOS, la aplicación pasa por los estados: Not Running → Active → Inactive → Background → Suspended. En Android — a través de onCreate → onStart → onResume → onPause → onStop → onDestroy + onRestart. Cada estado le da al desarrollador una ventana para guardar el estado, liberar recursos o prepararse para el regreso. Según la Documentación de Apple, ignorar los eventos del lifecycle es la causa del 40 % de los fallos al minimizar una aplicación. En IT Sectr implementamos ProcessLifecycleOwner en Android y el patrón AppDelegate en iOS como estándares obligatorios para todos los proyectos — esto redujo los errores relacionados con el fondo en un 60 %.

Puntos clave

  • App Lifecycle — conjunto de estados de la aplicación desde el inicio hasta la finalización, cada uno con acciones específicas del desarrollador.
  • AppDelegate — la clase central de iOS para el manejo del lifecycle: didFinishLaunching, didEnterBackground, willEnterForeground.
  • SceneDelegate — delegado de escenas individuales (iOS 13+), que gestiona el lifecycle de cada ventana en aplicaciones multiventana.
  • ProcessLifecycleOwner — componente de Android de AndroidX Lifecycle que rastrea el lifecycle de todo el proceso.
  • Application.onCreate — el primer punto de entrada de una aplicación Android, llamado antes que cualquier Activity.

¿Qué es App Lifecycle?

App Lifecycle es una máquina de estados finitos que describe todos los estados posibles de una aplicación móvil y las transiciones entre ellos. Cada estado determina si la aplicación puede ejecutar código, mostrar la interfaz de usuario y consumir recursos. iOS y Android tienen modelos similares pero no idénticos — las diferencias se deben a la arquitectura del SO: iOS utiliza un control de memoria estricto (estado suspended), mientras que Android utiliza una gestión flexible de procesos mediante onSaveInstanceState.

En iOS, el lifecycle está estrechamente vinculado al foreground/background: la aplicación está activa o suspendida. En Android, el lifecycle es más granular — una Activity/Ventana pasa por 6+ estados, y el proceso en sí tiene un lifecycle adicional a través de ProcessLifecycleOwner. Las aplicaciones modernas (desde 2024) utilizan cada vez más patrones de arquitectura basados en lifecycle: SwiftUI Lifecycle (iOS 16+) mediante el entorno .scenePhase, Compose Lifecycle mediante LifecycleEventObserver. Estos patrones manejan automáticamente el cambio de contexto y previenen fugas de memoria. Según Google, el manejo correcto del lifecycle en Android reduce el consumo de memoria entre un 30 y un 40 % durante el trabajo en segundo plano.

Ciclo de vida iOS: AppDelegate y SceneDelegate

En iOS, el ciclo de vida de la aplicación se gestiona a través de la clase UIApplicationDelegate (AppDelegate). Los métodos principales: application(_:didFinishLaunchingWithOptions:) — inicialización en el primer inicio; applicationDidBecomeActive — la aplicación es visible y está lista para la interacción; applicationWillResignActive — transición al estado inactivo (llamada entrante, cierre de la cortinilla de notificaciones); applicationDidEnterBackground — la aplicación está oculta, ~5 segundos para guardar datos; applicationWillEnterForeground — regreso del fondo; applicationWillTerminate — finalización (se llama solo para aplicaciones antiguas sin suspended).

A partir de iOS 13, Apple introdujo SceneDelegate (UISceneDelegate) para soportar aplicaciones multiventana en iPad y macOS Catalyst. SceneDelegate gestiona el lifecycle de cada escena (ventana) individual: scene(_:willConnectTo:options:) — creación de la escena; sceneDidBecomeActive — la escena está activa; sceneWillResignActive — la escena pierde el foco; sceneDidEnterBackground — la escena está oculta. AppDelegate maneja eventos globales (carga de datos, notificaciones push), mientras que SceneDelegate maneja el estado de la interfaz de usuario de cada ventana. En SwiftUI, el lifecycle se maneja a través del valor del entorno @Environment(\.scenePhase): .active, .inactive, .background — esto proporciona una API unificada tanto para aplicaciones SwiftUI como UIKit.

Ciclo de vida Android: Application y ProcessLifecycleOwner

En Android, el ciclo de vida comienza con la clase Application — un singleton creado antes que cualquier Activity. El método Application.onCreate() es el primer punto de entrada, utilizado para la inicialización global (Analytics, DI, Crash Reporting). Después, se lanza la Activity con la secuencia: onCreate() → onStart() → onResume(). Al minimizar: onPause() → onStop() → onSaveInstanceState(). Al destruir: onDestroy(). Al regresar: onRestart() → onStart() → onResume().

ProcessLifecycleOwner (de AndroidX Lifecycle 2.2+) rastrea el lifecycle de todo el proceso, no de una Activity individual. Proporciona dos estados: ON_RESUME (aplicación en foreground) y ON_STOP (aplicación oculta). ProcessLifecycleOwner resuelve el problema de «cuándo la aplicación pasó a segundo plano» a nivel de proceso — esto es crítico para SDK, bibliotecas y aplicaciones modulares. En Jetpack Compose, el lifecycle se gestiona a través de LifecycleEventObserver y collectAsStateWithLifecycle, que suspende automáticamente la recolección de datos en modo de segundo plano. Android 14 (API 34) agregó notificación de ciclo de vida del servicio en primer plano a través de Service.onTimeout — el servicio debe completarse en 6 horas, de lo contrario el sistema lo detiene forzosamente.

Comparación del ciclo de vida iOS y Android

iOS Android Descripción
Not Running La aplicación no está iniciada
didFinishLaunching Application.onCreate Primera inicialización al iniciar
Active onResume La aplicación es visible y acepta entrada
Inactive onPause Pérdida temporal de foco (llamada, cortinilla de notificaciones)
Background onStop La aplicación está oculta, el código puede ejecutarse
Suspended El código no se ejecuta, la memoria está reservada
Will Terminate onDestroy La aplicación está finalizando

La principal diferencia: iOS fuerza la transición de la aplicación a Suspended (el código deja de ejecutarse) 5-10 segundos después de entrar en segundo plano. Android permite el trabajo en segundo plano (servicios, WorkManager) durante un período más largo, pero con limitaciones del Modo Doze (Android 6+) y restricciones de fondo (Android 12+). ProcessLifecycleOwner en Android es el equivalente de UIApplicationDidEnterBackgroundNotification en iOS, con la diferencia de que se activa en cualquier transición a segundo plano, no solo después de perder el foco.

Ejemplos de código

iOS: AppDelegate con métodos de ciclo de vida

Implementación básica de AppDelegate manejando todos los estados del ciclo de vida. Guardar datos al pasar a segundo plano y actualizar la interfaz de usuario al regresar.

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 es el punto central del ciclo de vida. applicationDidEnterBackground es un método crítico: iOS da ~5 segundos para guardar. applicationDidBecomeActive — actualice la interfaz de usuario, reinicie animaciones. Para SceneDelegate (iOS 13+), la lógica del ciclo de vida se distribuye entre escenas: sceneDidBecomeActive / sceneDidEnterBackground gestionan ventanas individuales.

iOS: SceneDelegate (iOS 13+)

SceneDelegate para aplicaciones multiventana de iPad. Cada escena tiene su propio ciclo de vida, independiente de otras ventanas.

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 gestiona el ciclo de vida de una escena individual. sceneDidBecomeActive / sceneDidEnterBackground son los equivalentes de los métodos de AppDelegate para una ventana específica. sceneDidDisconnect se llama al cerrar una escena (el usuario cerró una ventana en iPad). Para compatibilidad con iOS 12 e inferiores, AppDelegate debe duplicar la lógica de SceneDelegate. En iOS 17+, puede usar @Observable para pausar/reanudar automáticamente tareas según scenePhase.

Android: Application con ProcessLifecycleOwner

ProcessLifecycleOwner rastrea cuándo la aplicación está en foreground/background a nivel de proceso. Este es el enfoque óptimo para la gestión global del ciclo de vida.

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 es la única forma correcta de rastrear la transición a segundo plano a nivel de aplicación. ON_START se activa cuando la aplicación se vuelve visible (foreground), ON_STOP — cuando está completamente oculta (background). A diferencia del ciclo de vida de Activity, ProcessLifecycleOwner no está vinculado a una pantalla específica. Para Jetpack Compose, use LifecycleResumeEffect o collectAsStateWithLifecycle en lugar de la observación manual.

Android: Ciclo de vida de Activity con ViewModel

ViewModel + Lifecycle es la arquitectura correcta de Android para la gestión del ciclo de vida. ViewModel se limpia automáticamente en onDestroy, evitando fugas de memoria.

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 — liberando recursos")
    }
}

// En 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 — pausando animaciones")
    }

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

ViewModel sobrevive a la rotación de pantalla y se destruye solo cuando finaliza la Activity. onCleared() es el lugar para liberar recursos y cancelar suscripciones a flujos. LiveData pausa automáticamente la observación en onPause y la reanuda en onResume — esto proporciona protección contra fugas y fallos durante el trabajo en segundo plano. En Compose, use collectAsStateWithLifecycle() para el mismo propósito.

Preguntas frecuentes

¿Qué sucede cuando un usuario minimiza una aplicación de iOS?

Al minimizar, la aplicación pasa de activo a inactivo (brevemente), luego a segundo plano. Después de unos segundos, el sistema puede moverla a suspended — el código deja de ejecutarse, la memoria está reservada. Cuando hay poca memoria, el sistema termina la aplicación suspendida (no se llama a willTerminate). Guarde sus datos en applicationDidEnterBackground — este es el último punto garantizado para guardar.

¿Es necesario manejar todos los estados de App Lifecycle?

Mínimo obligatorio: applicationDidEnterBackground — guardar datos del usuario; applicationWillEnterForeground — actualizar la interfaz de usuario; en Android onPause — pausar animaciones/sensores. ProcessLifecycleOwner simplifica el manejo: onResume — onPause para foreground, onStart — onStop para visibilidad. Maneje los otros estados según sea necesario — no todos los estados son críticos para cada aplicación.

¿En qué se diferencia SceneDelegate de AppDelegate?

AppDelegate es el delegado global de toda la aplicación (inicio, transición a segundo plano). SceneDelegate (iOS 13+) gestiona el ciclo de vida de una ventana individual (escena) — en aplicaciones multiventana de iPad, cada escena tiene su propio ciclo de vida. Para iOS 12 e inferiores, todo el ciclo de vida se maneja a través de AppDelegate. Con iPadOS 16+, SceneDelegate es obligatorio para Stage Manager.

¿Qué es ProcessLifecycleOwner en Android?

ProcessLifecycleOwner es un componente de AndroidX Lifecycle que rastrea el ciclo de vida de toda la aplicación (proceso), no de una Activity individual. Proporciona dos eventos principales: ON_RESUME (aplicación en foreground) y ON_STOP (aplicación en background). Se utiliza para la inicialización/limpieza de SDK, análisis, monitores de red — todo lo que deba reaccionar a la transición de la aplicación a segundo plano, independientemente de la pantalla actual.

¿Cómo manejar el ciclo de vida en Jetpack Compose?

En Jetpack Compose, use LifecycleEventObserver a través de LocalLifecycleOwner.current.lifecycle o la función collectAsStateWithLifecycle(). Para pantallas de Compose, use LifecycleResumeEffect — similar a DisposableEffect, que se ejecuta en onResume y se limpia en onPause. lifecycleScope.launchWhenResumed — una corrutina que se suspende automáticamente en segundo plano.

Resumen

  • App Lifecycle es una máquina de estados finitos de la aplicación que determina la gestión de recursos, la persistencia de datos y la estabilidad.
  • iOS AppDelegate (applicationDidEnterBackground) es el método crítico para guardar datos al pasar a segundo plano en 5 segundos.
  • iOS SceneDelegate (iOS 13+) gestiona el ciclo de vida de cada escena por separado — obligatorio para aplicaciones multiventana de iPad.
  • Android ProcessLifecycleOwner es un observador global del ciclo de vida del proceso para inicialización/limpieza de SDK.
  • ViewModel en Android sobrevive a la rotación de pantalla y se limpia al finalizar la Activity — previene fugas de memoria.
  • SwiftUI @Environment(\.scenePhase) proporciona una API unificada para el ciclo de vida en SwiftUI (active, inactive, background).
  • El manejo correcto del ciclo de vida reduce el consumo de memoria entre un 30-40% y previene el 40% de los fallos durante el trabajo en segundo plano.

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también