Handler() obsoleto: ¿y ahora qué? Una mirada al 2025
\n\nSi alguna vez has programado para Android, seguramente has usado Handler() para cambiar entre hilos, tareas retrasadas o actualizar la UI. Esta vieja y querida clase ha estado con nosotros desde las primeras versiones de Android. Pero en 2024-2025, Google declaró oficialmente el constructor Handler() como deprecated (obsoleto). Miles de desarrolladores en Stack Overflow se preguntan: «What do I use now that Handler() is deprecated?»
En este artículo analizaremos por qué Handler() está obsoleto, qué alternativas ofrece Android en 2025 y, lo más importante, cómo escribir código moderno y limpio en Kotlin que no haga llorar a tu líder técnico. ¡Allá vamos!
¿Por qué Handler() se volvió obsoleto?
\n\nLa clase Handler en sí no ha desaparecido. Lo que está obsoleto es específicamente el constructor sin argumentos (Handler()) y sus sobrecargas, que creaban implícitamente un Looper del hilo actual. El problema es que este comportamiento:
- \n
- Es implícito e inseguro — si llamas a
Handler()en un hilo en segundo plano que no tieneLooper, obtendrás unRuntimeException. \n - Complica las pruebas —
Handlerestá fuertemente ligado al ciclo de vida de los hilos, lo que hace que las pruebas unitarias sean un dolor de cabeza. \n - Está moralmente obsoleto — han surgido herramientas más modernas y declarativas: corrutinas,
HandlerThread(de forma explícita) yLiveData. \n
Google recomienda pasar explícitamente el Looper al constructor, o usar alternativas. Veamos qué ha llegado para reemplazarlo.
Alternativa n.º 1: Looper explícito (la solución más simple)
\n\nSi no quieres reescribir todo el código, la forma más rápida de eliminar la advertencia de obsoleto es pasar Looper explícitamente. Para el hilo principal (UI thread), usa Looper.getMainLooper().
// Código antiguo (obsoleto)\nval handler = Handler()\n\n// Código nuevo (2025)\nval handler = Handler(Looper.getMainLooper())\n\n// O para un hilo en segundo plano:\nval handler = Handler(Looper.myLooper()) // ¡Cuidado: puede ser null!\n\n\nEsto no resolverá todos los problemas, pero eliminará la advertencia del compilador. Sin embargo, para proyectos serios, es mejor migrar a corrutinas.
\n\nAlternativa n.º 2: Kotlin Coroutines (recomendada por Google)
\n\nDesde 2021, Google recomienda oficialmente Kotlin Coroutines para operaciones asíncronas. En 2025, esto ya es un estándar de la industria. ¿Por qué las corrutinas son mejores que Handler?
- \n
- Ligereza — miles de corrutinas no bloquean los hilos. \n
- Concurrencia estructurada — cancelación automática al finalizar el ciclo de vida. \n
- Legibilidad — el código se ve como síncrono, sin callbacks. \n
- Capacidad de prueba —
runBlockingyTestCoroutineDispatcherpara pruebas unitarias. \n
Así es como se reemplazan las tareas típicas de Handler con corrutinas:
Reemplazo de postDelayed (tarea retrasada)
\n\n// Forma antigua con Handler\nval handler = Handler(Looper.getMainLooper())\nhandler.postDelayed({\n // ejecutar después de 2 segundos\n}, 2000)\n\n// Forma nueva con Coroutines\nlifecycleScope.launch {\n delay(2000) // ¡no bloquea el hilo!\n // ejecutar después de 2 segundos\n}\n\n\nReemplazo de post (cambio al hilo de UI)
\n\n// Forma antigua\nhandler.post {\n textView.text = "Hola desde el hilo en segundo plano"\n}\n\n// Forma nueva\nlifecycleScope.launch(Dispatchers.Main) {\n textView.text = "Hola desde la corrutina"\n}\n\n\nReemplazo de removeCallbacks (cancelación de tarea)
\n\n// Forma antigua\nval runnable = Runnable { /*...*/ }\nhandler.postD