onResume es un método del ciclo de vida de Android que se llama cuando una Activity o Fragment pasa al primer plano y recibe el foco de entrada. En este estado, la pantalla está lista para la interacción con el usuario: todos los eventos táctiles, pulsaciones de teclas y gestos se dirigen a este componente. onResume es el estado de trabajo de una Activity, donde la aplicación pasa la mayor parte del tiempo. Aquí es donde se abre la cámara, se inicia la reproducción de video, se comienza el reconocimiento de voz y se registran listeners de sensores que requieren acceso exclusivo. Para más información sobre el ciclo de vida completo de una Activity, lea el artículo Activity Lifecycle.
Puntos clave
onResume — el tercer método del ciclo de vida de una Activity, llamado después de onStart, que señala que la pantalla está lista para la interacción completa con el usuario. En este momento, la Activity está en la cima de la pila de tareas (back stack), el sistema le dirige todos los eventos de entrada, y la aplicación puede comenzar cualquier operación que requiera la participación activa del usuario: videollamadas, juegos, grabación de audio, dibujo en Canvas.
onResume forma parte del “ciclo de vida en primer plano” (foreground lifetime) — el intervalo entre onResume y onPause. Este es el período más activo de una Activity, cuando la aplicación consume la mayor cantidad de recursos: CPU para procesar toques, GPU para renderizar animaciones, cámara y micrófono para captura de video. Comprender este nivel del ciclo de vida es fundamental para optimizar el consumo de energía: los recursos abiertos en onResume deben cerrarse inmediatamente en onPause.
Según Google I/O 2025, el tiempo promedio que una Activity pasa en el estado onResume por sesión es de 2 a 5 minutos para aplicaciones de noticias y de 15 a 30 minutos para juegos y mensajería. El resto del tiempo, la Activity está en los estados onPause, onStop u onDestroy. Esto significa que optimizar específicamente el código de onResume proporciona los mayores beneficios en rendimiento y duración de la batería.
En una Activity, el método onResume se llama cada vez que la pantalla recibe el foco de entrada — al iniciar por primera vez, al regresar de otra Activity, al cerrar un diálogo, al desbloquear el dispositivo. Este es un método “caliente” que puede llamarse muchas veces por sesión, y su implementación debe ser lo más ligera posible.
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
}
}
El ejemplo con CameraX demuestra el uso clásico de onResume/onPause: la cámara es un recurso exclusivo que solo una aplicación puede usar a la vez. Vincular la cámara al ciclo de vida mediante bindToLifecycle cierra automáticamente la cámara en onPause, pero una llamada explícita a unbindAll garantiza la liberación inmediata. Esto es especialmente importante al cambiar entre Activities: la cámara debe liberarse antes de que otra Activity intente abrirla.
onResume en un Fragment se llama después de que la Activity que lo contiene ha recibido onResume. Sin embargo, debido a las particularidades de FragmentManager y ViewPager, el momento de la llamada a onResume para un Fragment puede retrasarse con respecto a la Activity. Por ejemplo, un Fragment en un ViewPager con offscreenPageLimit = 1 recibe onResume solo cuando se convierte en la página actual, no al iniciar la 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 comprobación de userVisibleHint en Fragment.onResume es relevante para ViewPager: un Fragment puede recibir onResume pero estar oculto por una página vecina (por ejemplo, durante una transición animada). En tales casos, iniciar video o biometría en onResume sin verificar la visibilidad provocará un comportamiento inesperado. A partir de Fragment 1.5.0, se recomienda usar FragmentTransaction.setMaxLifecycle() para un control preciso del ciclo de vida de los fragmentos en ViewPager2.
Los desarrolladores a menudo confunden onStart y onResume, colocando el código en el método incorrecto. La regla principal: onStart — para recursos que funcionan mientras son visibles; onResume — para recursos que requieren foco de entrada. Veamos escenarios específicos y la elección correcta del método.
| Operación | Método | Justificación |
|---|---|---|
| Suscripción a geolocalización | onStart / onStop | El GPS puede funcionar con visibilidad parcial |
| Abrir la cámara | onResume / onPause | La cámara es un recurso exclusivo |
| BroadcastReceiver | onStart / onStop | Los eventos del sistema no requieren foco |
| Reproducción de video | onResume / onPause | El video debe ser visible para el usuario |
| Escaneo Bluetooth | onStart / onStop | El escaneo puede ejecutarse en segundo plano |
| Grabadora de voz (MediaRecorder) | onResume / onPause | La grabación requiere UI activa |
| Listeners de sensores | onResume / onPause | Sensores para juegos y gestos |
| Actualización de datos | onStart | Datos actualizados necesarios al aparecer |
Una regla práctica: si una operación debe interrumpirse cuando aparece un diálogo — use onResume/onPause. Si una operación puede continuar cuando la pantalla está parcialmente cubierta — use onStart/onStop. Por ejemplo, un reproductor de video debe pausar el video al abrir un diálogo (onPause), mientras que la geolocalización puede continuar actualizándose (permanece en onStart).
Los recursos exclusivos son componentes del dispositivo que solo una aplicación puede usar en un momento determinado. Cámara, micrófono, salida de video (MediaProjection), adaptador NFC en modo lectura, dispositivos USB en modo accessory — todos estos recursos deben abrirse en onResume y liberarse en onPause.
MediaRecorder se utiliza para grabar audio y video. Las solicitudes de permisos y la preparación de MediaRecorder se realizan en onCreate, mientras que la grabación comienza en onResume. Si el usuario cambia a otra aplicación, onPause pausa la grabación y onResume la reanuda. Este es el comportamiento estándar para grabadoras de voz y aplicaciones de grabación de video.
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()
}
La autenticación biométrica (BiometricPrompt) debe llamarse solo cuando la Activity está en onResume. Si se llama en onCreate u onStart, el diálogo de biometría puede aparecer antes de que la Activity termine la inicialización, lo que provocará un manejo incorrecto del resultado. Llamarlo en onResume garantiza que la ventana de biometría se muestre en el contexto correcto.
Veamos tres patrones probados para trabajar con onResume utilizados en proyectos comerciales: reinicio del temporizador de inactividad, actualización de datos visibles e integración con Jetpack Navigation.
En aplicaciones con datos confidenciales (banca, historiales médicos), onResume se usa para reiniciar el temporizador de cierre de sesión automático. Si el usuario interactúa activamente con la aplicación, onResume se llama en cada transición de pantalla y el temporizador se reinicia. Si el usuario minimiza la aplicación, onPause detiene el temporizador, y onResume al regresar lo reinicia o solicita una nueva autenticación.
Una lista que debe mostrar datos actualizados cada vez que se vuelve a la pantalla se actualiza en onResume. Por ejemplo, si el usuario creó una nueva entrada en otra Activity y volvió atrás, onResume recarga la lista desde la base de datos local o desde el caché de ViewModel. Esto garantiza la consistencia de los datos sin necesidad de llamar manualmente a notifyDataSetChanged.
override fun onResume() {
super.onResume()
// ActivityResultLauncher devolvió un resultado — actualizando la lista
viewModel.refreshList()
// Reinicio del temporizador de inactividad
inactivityTimer.reset()
}
En Jetpack Navigation, onResume de un fragment se llama cada vez que se regresa a él mediante navegación hacia atrás. Esta propiedad se utiliza para restablecer el estado de la UI: ocultar el teclado, limpiar los campos de búsqueda, actualizar el título de la barra de herramientas. OnBackPressedCallback combinado con onResume proporciona un control total sobre la navegación sin duplicación de código.
Preguntas frecuentes
onStart — la pantalla es visible. onResume — la pantalla está activa y lista para la interacción. Imagínese: está viendo la televisión (onStart), pero toma el control remoto (onResume). La televisión siempre es visible, pero la interacción solo comienza con el control remoto. Si alguien cubre la televisión con una cortina — la pantalla deja de ser visible (onStop). Si le quitan el control remoto — la interacción se detiene (onPause), pero la televisión sigue siendo visible.
onResume se llama cada vez que la Activity recibe el foco de entrada. El mínimo es una vez (al iniciar). El máximo depende de los escenarios de uso: cambiar entre pantallas, abrir diálogos, bloquear y desbloquear rápidamente el dispositivo — cada uno de estos escenarios llama a onResume al regresar a la pantalla.
La cámara es un recurso exclusivo disponible solo para una aplicación a la vez. Si abre la cámara en onCreate u onStart, permanecerá bloqueada para otras aplicaciones incluso cuando su aplicación esté inactiva. onResume garantiza que la cámara esté abierta solo cuando la Activity esté en primer plano, y onPause la cierra inmediatamente. Este es un estándar de desarrollo de Android, establecido en la documentación de CameraX y Camera2 API.
Sí, onResume puede no ocurrir si una Activity es superpuesta por otra Activity inmediatamente después de aparecer. Por ejemplo, la Activity A inicia la Activity B en el método onCreate u onStart. En este caso, A recibe onStart → onPause → onStop, omitiendo onResume. El sistema no llama a onResume porque la Activity A nunca recibió foco de entrada.
En onResume, no se deben realizar operaciones sincrónicas largas: cargar grandes cantidades de datos desde la red, consultas SQL complejas, procesamiento de imágenes. onResume se ejecuta en el hilo de UI, y cualquier bloqueo de más de 100–200 ms causa retraso en la respuesta de la interfaz. Todas las operaciones pesadas deben ser asíncronas — mediante corrutinas, RxJava o WorkManager. Tampoco se recomienda llamar a finish() en onResume sin verificar — esto puede provocar un bucle infinito de recreación.
Resumen
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.
Lea también