Programação Assíncrona em Kotlin: guia completo

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Programação Assíncrona em Kotlin: Guia Completo

Programação assíncrona é uma abordagem de desenvolvimento na qual o programa não bloqueia a execução enquanto espera a conclusão de operações longas (por exemplo, requisições de rede, leitura de arquivos ou trabalho com banco de dados). Em vez disso, ele continua executando outras tarefas, e o resultado é retornado posteriormente. No mundo Kotlin, a principal ferramenta para trabalho assíncrono são as corrotinas (coroutines) — threads leves que permitem escrever código assíncrono quase como síncrono.

Neste artigo, vamos analisar como funciona a programação assíncrona em Kotlin, desde os fundamentos até técnicas avançadas. Você aprenderá como usar corrotinas de forma eficiente, evitar bloqueios e escrever aplicações escaláveis.



1. Fundamentos das Corrotinas em Kotlin

Corrotinas são o conceito-chave da programação assíncrona em Kotlin. Elas permitem pausar a execução de uma função sem bloquear a thread. Para trabalhar com corrotinas, utiliza-se a biblioteca kotlinx.coroutines. Aqui está um exemplo mínimo:

import kotlinx.coroutines.*

fun main() = runBlocking { launch { delay(1000L) // atraso não bloqueante println("Mundo!") } println("Olá,")}

Neste código, runBlocking cria um contexto bloqueante para a corrotina (geralmente usado apenas no main ou em testes), e launch inicia uma nova corrotina. A função delay é uma função suspend que pausa a corrotina sem bloquear a thread.

Conceitos-chave:

  • CoroutineScope — escopo de visibilidade das corrotinas, gerencia seu ciclo de vida.
  • CoroutineContext — conjunto de configurações (dispatcher, manipulador de exceções).
  • Função Suspend — função que pode ser pausada e retomada posteriormente.


2. Funções Suspend e Dispatchers

Funções Suspend são a base do código assíncrono. Elas podem chamar outras funções suspend (delay, withContext) e pausar sua execução. Exemplo:

suspend fun fetchUserData(): String {    delay(2000L) // simulação de requisição de rede    return "Dados do usuário"}

fun main() = runBlocking { val data = async { fetchUserData() } println("Carregando...") println(data.await()) // aguardando o resultado}

Dispatchers determinam em qual thread a corrotina será executada:

  • Dispatchers.Default — para tarefas intensivas de CPU (padrão).
  • Dispatchers.IO — para operações de entrada/saída (rede, arquivos).
  • Dispatchers.Main — para a thread da UI (Android, Swing).
  • Dispatchers.Unconfined — não vinculado a uma thread específica (raramente usado).

Exemplo com troca de dispatcher:

suspend fun loadData(): String = withContext(Dispatchers.IO) {    // executando operação pesada em thread de fundo    Thread.sleep(1000L) // simulação de operação bloqueante    "Resultado"}

Usar o dispatcher correto é criticamente importante para o desempenho. Não use Dispatchers.Main para operações longas — isso bloqueará a UI.



3. Trabalhando com async/await e Canais

Para execução paralela de múltiplas tarefas, use async e await. async retorna um objeto Deferred, que pode ser aguardado:

fun main() = runBlocking {    val result1 = async(Dispatchers.IO) { fetchFromApi("url1") }    val result2 = async(Dispatchers.IO) { fetchFromApi("url2") }    println("Resultado 1: ${result1.await()}")    println("Resultado 2: ${result2.await()}")}

suspend fun fetchFromApi(url: String): String { delay(1000L) return "Resposta de $url"

Blogs

Book Recommendations