O que são coroutines em Kotlin?
Se você já estudou um pouco de Kotlin, com certeza já ouviu falar em coroutines. Esse é um dos recursos mais poderosos da linguagem, mas também um dos que mais gera dúvida. Bora desmistificar?
Explicando de forma simples
Coroutines são uma forma de escrever código assíncrono de maneira sequencial e legível. Em vez de lidar com callbacks aninhados (o famoso “callback hell”) ou com APIs complicadas de threads, você escreve código que parece síncrono, mas que por baixo dos panos não bloqueia a thread principal.
Pense assim: imagine que você está num restaurante. Em vez de ficar parado esperando o prato ficar pronto (bloqueando), você faz o pedido e vai fazer outra coisa enquanto a cozinha trabalha. Quando o prato fica pronto, você volta pra comer. É isso que uma coroutine faz com seu código.
Um exemplo prático
import kotlinx.coroutines.*
fun main() = runBlocking {
println("Começando o programa...")
// Lança duas coroutines que rodam "ao mesmo tempo"
val pedido1 = async { buscarDados("Usuários", 2000) }
val pedido2 = async { buscarDados("Produtos", 1500) }
// Espera os dois resultados
println(pedido1.await())
println(pedido2.await())
println("Tudo pronto!")
}
suspend fun buscarDados(tipo: String, tempoMs: Long): String {
delay(tempoMs) // Simula uma operação demorada (não bloqueia a thread!)
return "Dados de $tipo carregados com sucesso"
}
Nesse exemplo, as duas buscas acontecem simultaneamente, e o tempo total é determinado pela mais lenta (2 segundos), e não pela soma das duas (3,5 segundos). Isso faz uma diferença enorme em aplicações reais.
Conceitos fundamentais
suspend fun: marca uma função que pode ser suspensa e retomada sem bloquear a threadlaunch: inicia uma coroutine sem esperar o resultado (tipo “dispara e esquece”)async/await: inicia uma coroutine e permite aguardar o resultado depoisrunBlocking: cria um escopo de coroutine bloqueante, usado normalmente nomainou em testesdelay: pausa a coroutine sem bloquear a thread (diferente deThread.sleep)
Por que coroutines são tão importantes?
No desenvolvimento Android, a thread principal (UI thread) não pode ser bloqueada, senão o app trava. Coroutines resolvem isso de forma elegante, permitindo que operações pesadas como chamadas de API e acesso a banco de dados rodem sem congelar a interface.
No backend, coroutines permitem que um servidor atenda milhares de requisições simultâneas com muito menos recursos do que seria necessário usando threads tradicionais.
O principal cuidado
Coroutines são leves, mas não são mágicas. É importante entender os escopos e o ciclo de vida de cada coroutine pra evitar vazamentos de memória e comportamentos inesperados. No Android, por exemplo, use viewModelScope ou lifecycleScope em vez de criar escopos soltos.
Dominar coroutines leva um tempinho, mas é um investimento que vale muito a pena. É um daqueles conhecimentos que transformam a forma como você programa.