Handler() está obsoleto: e agora? Uma visão para 2025
\n\nSe você já programou para Android, certamente usou Handler() para alternar entre threads, tarefas atrasadas ou atualizar a UI. Esta velha e boa classe esteve conosco desde as primeiras versões do Android. Mas em 2024-2025, o Google declarou oficialmente o construtor Handler() como deprecated (obsoleto). Milhares de desenvolvedores no Stack Overflow perguntam: "O que usar agora que Handler() está obsoleto?"
Neste artigo, vamos entender por que Handler() está obsoleto, quais alternativas o Android oferece em 2025 e, o mais importante, como escrever código moderno e limpo em Kotlin que não fará seu tech lead chorar. Vamos lá!
Por que Handler() se tornou deprecated?
\n\nA classe Handler em si não desapareceu. O que está obsoleto é o construtor sem argumentos (Handler()) e suas sobrecargas, que criavam implicitamente um Looper da thread atual. O problema é que esse comportamento:
- \n
- Implícito e inseguro — se você chamar
Handler()em uma thread em segundo plano que não possuiLooper, receberá umRuntimeException. \n - Dificulta os testes —
Handlerestá fortemente acoplado ao ciclo de vida das threads, tornando os testes unitários uma dor de cabeça. \n - Moralmente obsoleto — surgiram ferramentas mais modernas e declarativas: coroutines,
HandlerThread(de forma explícita) eLiveData. \n
O Google recomenda passar explicitamente o Looper no construtor ou usar alternativas. Vamos ver o que veio para substituir.
Alternativa nº1: Looper explícito (a correção mais simples)
\n\nSe você não quer reescrever todo o código, a maneira mais rápida de remover o deprecated é passar o Looper explicitamente. Para a thread principal (UI thread), use Looper.getMainLooper().
// Código antigo (deprecated)\nval handler = Handler()\n\n// Novo código (2025)\nval handler = Handler(Looper.getMainLooper())\n\n// Ou para uma thread em segundo plano:\nval handler = Handler(Looper.myLooper()) // Atenção: pode ser null!\n\n\nIsso não resolverá todos os problemas, mas removerá o aviso do compilador. No entanto, para projetos sérios, é melhor migrar para coroutines.
\n\nAlternativa nº2: Kotlin Coroutines (recomendado pelo Google)
\n\nDesde 2021, o Google recomenda oficialmente o Kotlin Coroutines para operações assíncronas. Em 2025, isso já é o padrão da indústria. Por que coroutines são melhores que Handler?
- \n
- Leveza — milhares de coroutines não bloqueiam threads. \n
- Concorrência estruturada — cancelamento automático ao final do ciclo de vida. \n
- Legibilidade — o código parece síncrono, sem callbacks. \n
- Testabilidade —
runBlockingeTestCoroutineDispatcherpara testes unitários. \n
Veja como substituir tarefas típicas do Handler por coroutines:
Substituindo postDelayed (tarefa atrasada)
\n\n// Método antigo com Handler\nval handler = Handler(Looper.getMainLooper())\nhandler.postDelayed({\n // executar após 2 segundos\n}, 2000)\n\n// Novo método com Coroutines\nlifecycleScope.launch {\n delay(2000) // não bloqueia a thread!\n // executar após 2 segundos\n}\n\n\nSubstituindo post (alternar para a thread da UI)
\n\n// Método antigo\nhandler.post {\n textView.text = "Olá da thread em segundo plano"\n}\n\n// Novo método\nlifecycleScope.launch(Dispatchers.Main) {\n textView.text = "Olá da coroutine"\n}\n\n\nSubstituindo removeCallbacks (cancelar tarefa)
\n\n// Método antigo\nval runnable = Runnable { /*...*/ }\nhandler.postD