lifecycleScope: qué es, vinculación con Lifecycle y trabajo en Android

Autor: IT Sectr Publicado: 2026-06-23 Tiempo de lectura: 9 min

lifecycleScope — es un CoroutineScope integrado de la biblioteca androidx.lifecycle, vinculado al ciclo de vida de una Activity, Fragment o cualquier LifecycleOwner, y cancela automáticamente las corrutinas cuando el componente se destruye. Según Google Android Developers, 2025, lifecycleScope permite ejecutar corrutinas de forma segura en la capa de UI sin riesgo de ejecutar código después de que la Activity o Fragment se destruya. El scope se cancela automáticamente cuando el LifecycleOwner pasa al estado DESTROYED.

Conclusiones clave

  • lifecycleScope — CoroutineScope de lifecycle-runtime-ktx, cancelado en el estado DESTROYED del Lifecycle
  • lifecycleScope.launch — lanzar una corrutina que se cancela automáticamente cuando el LifecycleOwner se destruye
  • launchWhenStarted / launchWhenResumed — métodos obsoletos, reemplazados por repeatOnLifecycle
  • repeatOnLifecycle — API moderna para lanzar corrutinas que siguen un estado específico del Lifecycle
  • Dispatchers.Main.immediate — dispatcher predeterminado para lifecycleScope

¿Qué es lifecycleScope en Android?

lifecycleScope es una propiedad de extensión en la interfaz LifecycleOwner (Activity, Fragment, Service) que proporciona un CoroutineScope listo, vinculado al ciclo de vida completo del componente. Cuando el LifecycleOwner alcanza el estado DESTROYED, lifecycleScope cancela automáticamente todas las corrutinas activas.

kotlin
// In Fragment or Activity
lifecycleScope.launch {
    delay(1000)
    showSnackbar("¡Hola!")
}

A diferencia de viewModelScope, lifecycleScope se cancela cada vez que el LifecycleOwner se destruye — incluida la rotación de pantalla. Esto lo hace ideal para operaciones que solo deben vivir mientras una pantalla específica esté visible.

Dónde está disponible lifecycleScope

lifecycleScope está disponible en cualquier lugar donde haya un LifecycleOwner:

  • Activity — AppCompatActivity hereda de LifecycleOwner
  • Fragment — Fragment hereda de LifecycleOwner
  • LifecycleService — un servicio con ciclo de vida
  • ProcessLifecycleOwner — el ciclo de vida de toda la aplicación
  • Custom LifecycleOwner — cualquier objeto que implemente LifecycleOwner

Cómo funciona lifecycleScope: Lifecycle y cancelación automática

El mecanismo de cancelación automática de lifecycleScope se basa en la suscripción a eventos de Lifecycle. Cuando el Lifecycle baja de CREATED a DESTROYED, el scope se cancela.

Estados del Lifecycle

EstadoDescripciónScope activo
CREATEDLifecycleOwner creado, onCreate ejecutado
STARTEDLifecycleOwner visible (onStart)
RESUMEDLifecycleOwner en primer plano (onResume)
DESTROYEDLifecycleOwner destruido (onDestroy)No (scope cancelado)

Estructura interna de lifecycleScope

lifecycleScope se crea como CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate) y se almacena dentro del Lifecycle. Cuando el Lifecycle transiciona al estado DESTROYED, se llama a scope.cancel(). El mecanismo se implementa a través de LifecycleEventObserver, que se suscribe a los eventos del ciclo de vida en el primer acceso al scope.

Comportamiento en rotación

Cuando la pantalla se rota, la Activity se destruye (onDestroy) y se recrea. lifecycleScope se cancela junto con la Activity anterior, y se crea una nueva instancia del scope para la nueva Activity. Esta es una diferencia fundamental con viewModelScope, que sobrevive a la rotación.

API de lifecycleScope: launch, launchWhen y repeatOnLifecycle

La biblioteca lifecycle proporciona varias formas de lanzar corrutinas a través de lifecycleScope. Veamos la evolución de la API desde los métodos obsoletos hasta los modernos.

lifecycleScope.launch — Lanzamiento básico

La forma más simple es lifecycleScope.launch { ... }. La corrutina se inicia inmediatamente y se cancela en DESTROYED. Sin embargo, puede ejecutar código incluso cuando la UI no es visible (por ejemplo, en segundo plano después de onStop). Esto no siempre es deseable.

Obsoletos: launchWhenCreated / launchWhenStarted / launchWhenResumed

Estos métodos pausaban la ejecución de la corrutina cuando el Lifecycle bajaba del estado especificado y la reanudaban al regresar. Sin embargo, fueron marcados como @Deprecated en lifecycle-runtime-ktx 2.6.0 porque:

  • No cancelaban la corrutina — solo la pausaban
  • Provocaban la acumulación de corrutinas en pausa que consumen memoria
  • Creaban condiciones de carrera al cambiar rápidamente de estado

API moderna: repeatOnLifecycle

repeatOnLifecycle es la forma recomendada por Google para lanzar corrutinas sincronizadas con el ciclo de vida. Cancela y reinicia la corrutina cada vez que el Lifecycle alcanza el estado especificado.

kotlin
lifecycleScope.launch {
    repeatOnLifecycle(Lifecycle.State.STARTED) {
        viewModel.uiState.collect { state ->
            updateUI(state)
        }
    }
}

La corrutina pasada a repeatOnLifecycle se inicia cuando el Lifecycle alcanza STARTED y se cancela cuando baja de STARTED. Al regresar a STARTED, la corrutina se reinicia desde cero. Esto es seguro y eficiente — ninguna corrutina queda en pausa.

flowWithLifecycle — Para Flow

Para recolectar datos de Flow con conciencia del ciclo de vida, existe el operador flowWithLifecycle. Detiene y reanuda automáticamente la recolección cuando cambia el estado del Lifecycle:

kotlin
viewModel.uiState
    .flowWithLifecycle(lifecycle, Lifecycle.State.STARTED)
    .onEach { state -> updateUI(state) }
    .launchIn(lifecycleScope)

El operador flowWithLifecycle es la forma más concisa de suscribirse de forma segura a un Flow en la capa de UI.

Ejemplos de uso de lifecycleScope

Veamos tres escenarios reales de uso de lifecycleScope en una aplicación Android con Kotlin.

Ejemplo 1: Suscripción a actualizaciones de ubicación solo cuando la pantalla es visible

kotlin
class MapFragment : Fragment() {

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                locationProvider.observeLocation().collect { loc ->
                    updateMapMarker(loc)
                }
            }
        }
    }
}

La corrutina se inicia cuando el fragmento se vuelve visible (STARTED) y se cancela cuando sale de la pantalla (STOPPED). Si el usuario cambia a otra aplicación, las actualizaciones de ubicación no consumen batería.

Ejemplo 2: Iniciar una animación al iniciar el fragmento

kotlin
lifecycleScope.launch {
    repeatOnLifecycle(Lifecycle.State.RESUMED) {
        animateFadeIn(titleView)
        delay(200)
        animateSlideUp(contentView)
    }
}

La animación se ejecuta solo cuando el fragmento está en primer plano (RESUMED). Si el usuario minimiza la aplicación durante la animación, la corrutina se cancela, y al regresar, la animación se reinicia.

Ejemplo 3: Sincronización periódica de datos en una pantalla visible

kotlin
lifecycleScope.launch {
    repeatOnLifecycle(Lifecycle.State.STARTED) {
        while (isActive) {
            syncData()
            delay(30_000L)
        }
    }
}

Los datos se sincronizan cada 30 segundos, pero solo cuando la pantalla es visible. isActive verifica si la corrutina ha sido cancelada, proporcionando una forma segura de salir del ciclo al salir de la pantalla.

lifecycleScope vs viewModelScope: casos de uso

Ambos scopes están vinculados al ciclo de vida, pero a diferentes aspectos del mismo. Comprender la diferencia es crítico para una arquitectura adecuada de aplicaciones Android.

Diferencia clave

viewModelScope está vinculado al ViewModel, que sobrevive a la rotación de pantalla. lifecycleScope está vinculado al LifecycleOwner (Activity/Fragment), que se destruye y recrea en la rotación. Esto determina sus casos de uso.

Cuándo usar lifecycleScope

  • Suscripción a eventos del sistema (ubicación, sensores, cámaras)
  • Animaciones y efectos de UI vinculados a una pantalla específica
  • Carga de datos por fragmentos según la visibilidad de la pantalla
  • Operaciones que deben detenerse al salir de la pantalla

Cuándo usar viewModelScope

  • Carga de datos desde un Repository
  • Lógica de negocio que debe sobrevivir a la rotación
  • Almacenamiento en caché y procesamiento de datos
  • Cualquier operación cuyo resultado se necesite después de la rotación

Uso combinado

En la práctica, es común una combinación de ambos scopes: viewModelScope carga datos y gestiona el estado, mientras que lifecycleScope se suscribe al Flow del ViewModel con conciencia del ciclo de vida. Esta separación de responsabilidades se considera buena práctica en el desarrollo moderno de Android.

Errores comunes al trabajar con lifecycleScope

Veamos cuatro de los errores más comunes que cometen los desarrolladores al usar lifecycleScope.

Error 1: Usar lifecycleScope en lugar de viewModelScope para cargar datos

Si se lanza la carga de datos en lifecycleScope.launch, la corrutina se cancelará al rotar la pantalla y los datos tendrán que cargarse de nuevo. Use viewModelScope para operaciones de larga duración. lifecycleScope es solo para tareas vinculadas a la UI.

Error 2: Recolectar Flow sin repeatOnLifecycle

Llamar directamente a viewModel.someFlow.collect { ... } dentro de lifecycleScope.launch continúa recolectando datos incluso cuando la pantalla no es visible. Esto puede provocar actualizaciones de UI en segundo plano y una sobrecarga innecesaria. Use siempre repeatOnLifecycle o flowWithLifecycle.

Error 3: Olvidar la cancelación al salir de la pantalla

Aunque lifecycleScope se cancela en DESTROYED, el código después de un punto de suspensión puede no ejecutarse ante una cancelación repentina. No confíe en la ejecución posterior a una llamada suspend a menos que use NonCancellable.

Error 4: Usar el obsoleto launchWhenStarted en lugar de repeatOnLifecycle

launchWhenStarted y sus equivalentes no cancelan la corrutina, solo la pausan. Si la pantalla cambia entre primer plano y segundo plano varias veces, la corrutina acumula llamadas diferidas. Migre a repeatOnLifecycle — esta es la única forma correcta de sincronizarse con el Lifecycle.

Preguntas frecuentes

¿Cuál es la diferencia entre lifecycleScope y GlobalScope?

lifecycleScope se cancela automáticamente cuando el LifecycleOwner se destruye. GlobalScope vive durante toda la duración de la aplicación. Una corrutina en lifecycleScope no puede actualizar la UI después de que el componente se destruye, mientras que en GlobalScope puede hacerlo, lo que provoca fallos. Use siempre lifecycleScope en la capa de UI.

¿Se puede usar lifecycleScope en un ViewModel?

No, ViewModel no es un LifecycleOwner, por lo que lifecycleScope no está disponible en él. ViewModel usa viewModelScope. Si el código debe ejecutarse en ambos contextos, extraiga la lógica en un use case o repository con funciones suspend.

¿Qué sucede cuando se llama a repeatOnLifecycle varias veces?

Cada llamada a repeatOnLifecycle crea una nueva corrutina que ejecuta el bloque cuando se alcanza el estado especificado del Lifecycle. Si se llama a repeatOnLifecycle dos veces para el mismo estado, ambos bloques se ejecutarán de forma independiente. Normalmente, una sola llamada en onViewCreated es suficiente.

¿Se puede establecer un Dispatcher personalizado para lifecycleScope?

No se puede cambiar directamente el dispatcher de lifecycleScope — usa Dispatchers.Main.immediate. Dentro del bloque de la corrutina, se puede cambiar a otro dispatcher mediante withContext. Para pruebas, use TestDispatcher con LifecycleOwner.

¿LifecycleScope se cancela en onPause o en onDestroy?

lifecycleScope se cancela cuando el LifecycleOwner transiciona al estado DESTROYED (después de onDestroy). Las llamadas simples a lifecycleScope.launch no se cancelan en onPause ni en onStop. Para pausar al ir a segundo plano, use repeatOnLifecycle(STARTED) o repeatOnLifecycle(RESUMED).

Resumen

  • lifecycleScope — CoroutineScope vinculado a un LifecycleOwner y cancelado automáticamente en DESTROYED mediante LifecycleEventObserver
  • Dispatchers.Main.immediate — el dispatcher predeterminado, que garantiza actualizaciones seguras de la UI sin cambios innecesarios
  • repeatOnLifecycle — API moderna para lanzar corrutinas en un estado específico del Lifecycle con cancelación y reinicio automáticos
  • flowWithLifecycle — operador para la recolección segura de Flow desde la UI con conciencia del ciclo de vida
  • launchWhenStarted obsoleto — en lugar de pausar, use repeatOnLifecycle, que cancela la corrutina en lugar de pausarla
  • lifecycleScope vs viewModelScope — lifecycleScope para operaciones de UI (animaciones, ubicación), viewModelScope para datos y lógica de negocio
  • Rotación de pantalla — lifecycleScope se cancela en la rotación, viewModelScope sobrevive; elija el scope según la tarea

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