AsyncTask morreu? Viva as coroutines! Guia completo de migração para Kotlin
Se você abriu o Android Studio nos últimos anos, provavelmente viu este aviso triste: AsyncTask is deprecated. Sim, aquele fiel assistente para tarefas em segundo plano, que nos salvou desde o Android 1.5, foi oficialmente considerado obsoleto a partir do Android 11 (API 30).
Mas não entre em pânico! O Google não "matou" o AsyncTask à toa. Ele estava cheio de bugs ocultos, vazamentos de memória e problemas com o ciclo de vida. Neste artigo, vamos analisar os principais erros na migração do AsyncTask e mostrar quais ferramentas modernas vieram para substituí-lo. Você aprenderá a escrever código limpo, seguro e eficiente em Kotlin sem dor de cabeça.
Por que o AsyncTask se tornou um problema? (Breve introdução)
Antes de buscar alternativas, vamos lembrar como o AsyncTask nos "alegrava":
- Vazamentos de memória: Se uma Activity é destruída (rotação de tela) enquanto um AsyncTask ainda está em execução, ele mantém uma referência à Activity antiga, que o GC não consegue coletar.
- Complexidade com o ciclo de vida: A execução da tarefa não está vinculada ao ciclo de vida do componente. O resultado pode chegar a uma Activity já destruída.
- Execução sequencial: No Android 3.0+, o AsyncTask é executado sequencialmente em uma única thread por padrão, o que anula toda a ideia de paralelismo.
- Falta de cancelamento: O método
cancel()funciona incorretamente e muitas vezes não interrompe a thread.
Agora que relembramos essas dores, vamos para as soluções modernas que o Kotlin e o Android Jetpack oferecem.
Top 3 alternativas ao AsyncTask no Android 11+ (Kotlin)
Em vez de reinventar a roda, usamos ferramentas testadas. Aqui estão as melhores substituições para o AsyncTask que você precisa conhecer:
1. Kotlin Coroutines (Coroutines) — O principal assassino do AsyncTask
Esta é a forma mais moderna e recomendada pelo Google. As coroutines são leves, seguras e se integram perfeitamente com o Jetpack (ViewModel, LiveData, Room).
Exemplo: Carregar dados da rede (substituindo AsyncTask)
Em vez de escrever:
// AsyncTask antigo (NÃO FAÇA ISSO)class MyAsyncTask : AsyncTask<String, Void, String>() { override fun doInBackground(vararg params: String?): String { // Operação longa Thread.sleep(3000) return "Result" } override fun onPostExecute(result: String?) { textView.text = result }}Agora usamos coroutines:
// Nova abordagem com Kotlin Coroutinesclass MyViewModel : ViewModel() { private val _result = MutableLiveData<String>() val result: LiveData<String> = _result
fun fetchData() { viewModelScope.launch { // Executa em segundo plano val data = withContext(Dispatchers.IO) { // Simulação de operação longa delay(3000) "Result from Coroutine" } // Retorna automaticamente para a thread principal _result.value = data } }}Por que isso é legal? O viewModelScope cancela automaticamente a coroutine quando a ViewModel é destruída. Sem vazamentos! E o withContext(Dispatchers.IO) alterna o contexto de execução. O código é lido como síncrono, mas funciona de forma assíncrona.
2. RxJava / RxKotlin — Abordagem reativa
Se você gosta de fluxos de dados e operadores, o RxJava continua sendo uma ferramenta poderosa. No entanto, para tarefas simples, ele é excessivo. Use-o se o projeto já tiver Rx.
Exemplo: Single em vez de AsyncTask
// Alternativa ao AsyncTask com RxJavaclass DataRepository { fun fetchData(): Single<String> { return Single.fromCallable { // Trabalho em segundo plano