---
title: "Launch em Kotlin: O que É e Como Funciona | Kotlin Brasil"
url: "https://kotlin.dev.br/glossario/launch/"
markdown_url: "https://kotlin.dev.br/glossario/launch.MD"
description: "Aprenda o que é launch em Kotlin, como iniciar coroutines do tipo fire-and-forget e quando usar no seu projeto."
date: "2026-02-07"
author: "Karina Melo"
---

# Launch em Kotlin: O que É e Como Funciona | Kotlin Brasil

Aprenda o que é launch em Kotlin, como iniciar coroutines do tipo fire-and-forget e quando usar no seu projeto.


## O que é `launch` em Kotlin?

O `launch` é um **coroutine builder** que inicia uma nova coroutine sem retornar resultado. Ele é do tipo "fire-and-forget" — você dispara a coroutine e segue em frente. Perfeito pra tarefas que precisam rodar em background mas não precisam devolver um valor.

O `launch` retorna um `Job`, que permite controlar o ciclo de vida da coroutine: cancelar, esperar terminar ou verificar o status.

### Exemplo básico

```kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    val job = launch {
        println("Coroutine iniciada")
        delay(1000)
        println("Coroutine finalizada")
    }

    println("Código principal continua...")
    job.join() // Espera a coroutine terminar
}
```

Saída:
```
Código principal continua...
Coroutine iniciada
Coroutine finalizada
```

### Controlando com Job

O `Job` retornado pelo `launch` oferece várias possibilidades:

```kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    val job = launch {
        repeat(100) { i ->
            println("Processando item $i")
            delay(200)
        }
    }

    delay(1000)
    println("Cansou de esperar!")
    job.cancel()
    println("Job cancelado: ${job.isCancelled}")
}
```

### Dispatchers

Você pode escolher em qual thread a coroutine vai rodar:

```kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    launch(Dispatchers.Default) {
        println("CPU-intensivo em: ${Thread.currentThread().name}")
    }

    launch(Dispatchers.IO) {
        println("Operação de I/O em: ${Thread.currentThread().name}")
    }
}
```

- `Dispatchers.Default` — tarefas pesadas de CPU
- `Dispatchers.IO` — operações de entrada/saída
- `Dispatchers.Main` — thread principal (Android)

### `launch` vs `async`

A diferença é simples: `launch` não retorna valor, `async` retorna. Se você precisa do resultado da coroutine, use `async`. Se é só pra executar algo no background, `launch` resolve.

```kotlin
// Não precisa do resultado? Use launch
launch { salvarNoLog("evento_123") }

// Precisa do resultado? Use async
val dados = async { buscarDados() }
println(dados.await())
```

### Structured Concurrency com `launch`

O `launch` respeita o conceito de **structured concurrency** do Kotlin. Isso significa que uma coroutine filha está vinculada ao escopo pai. Se o escopo pai for cancelado, todas as coroutines filhas também são canceladas automaticamente.

```kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    val escopo = CoroutineScope(Dispatchers.Default)

    val jobPai = escopo.launch {
        launch {
            delay(2000)
            println("Filha 1 terminou") // Nunca será impresso
        }
        launch {
            delay(2000)
            println("Filha 2 terminou") // Nunca será impresso
        }
    }

    delay(500)
    jobPai.cancel() // Cancela o pai e todas as filhas
    println("Todas as coroutines foram canceladas")
}
```

### Tratamento de exceções com `launch`

Diferente do `async`, onde exceções são lançadas ao chamar `await()`, no `launch` as exceções propagam imediatamente para o escopo pai. Para interceptá-las, use um `CoroutineExceptionHandler`:

```kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    val handler = CoroutineExceptionHandler { _, excecao ->
        println("Exceção capturada: ${excecao.message}")
    }

    val escopo = CoroutineScope(Dispatchers.Default + handler)

    escopo.launch {
        throw RuntimeException("Algo deu errado!")
    }

    delay(500) // Aguarda para ver a saída
}
```

### Casos de Uso no Mundo Real

- **Envio de analytics e telemetria**: disparar eventos de rastreamento sem bloquear a interface do usuário. O resultado do envio não importa para o fluxo principal da aplicação.
- **Sincronização periódica de dados**: usar `launch` dentro de um loop com `delay` para sincronizar dados com o servidor a cada intervalo de tempo, como atualizar cache local.
- **Processamento de filas**: consumir itens de uma fila (mensagens, notificações, tarefas) em background, processando cada item de forma independente sem precisar do resultado.
- **Atualização de UI no Android**: disparar operações de atualização de tela a partir do `viewModelScope.launch`, garantindo que a coroutine seja cancelada automaticamente quando o ViewModel for destruído.

### Boas Práticas

- Sempre use `launch` dentro de um **CoroutineScope** bem definido. Evite usar `GlobalScope.launch`, pois ele não respeita o ciclo de vida da aplicação e pode causar vazamentos de memória.
- Prefira `Dispatchers.IO` para operações de rede e disco, e `Dispatchers.Default` para cálculos pesados. Nunca faça operações bloqueantes no `Dispatchers.Main`.
- Utilize `job.join()` quando precisar garantir que a coroutine terminou antes de prosseguir, mas evite usá-lo excessivamente — isso anula a vantagem da concorrência.
- Trate exceções com `CoroutineExceptionHandler` ou blocos `try/catch` dentro do `launch` para evitar crashes inesperados.
- Use `supervisorScope` quando quiser que a falha de uma coroutine filha não cancele as irmãs.

### Erros Comuns

- **Usar `GlobalScope.launch` indiscriminadamente**: isso cria coroutines que vivem durante toda a aplicação, podendo causar vazamentos de memória e comportamentos inesperados.
- **Esquecer de cancelar coroutines**: não vincular o `launch` a um escopo com ciclo de vida definido faz com que coroutines continuem rodando mesmo depois que a tela ou componente foi destruído.
- **Ignorar exceções**: como o `launch` propaga exceções para o escopo pai, não tratá-las pode derrubar toda a aplicação silenciosamente.
- **Bloquear a thread dentro do `launch`**: usar `Thread.sleep()` em vez de `delay()` bloqueia a thread e desperdiça os benefícios das coroutines.
- **Confundir `launch` com `async`**: tentar obter um resultado de `launch` não funciona. Se precisa de retorno, use `async` com `await()`.

### Perguntas Frequentes

**O `launch` bloqueia a thread?** Não. O `launch` inicia a coroutine de forma assíncrona e retorna imediatamente um `Job`. A thread que chamou o `launch` continua executando o código seguinte sem esperar.

**Quando usar `launch` em vez de `async`?** Use `launch` quando a tarefa não precisa devolver um resultado para quem a iniciou. Exemplos: salvar logs, enviar eventos de analytics, atualizar cache. Se precisa do valor de retorno, use `async`.

**O que acontece se uma exceção ocorrer dentro do `launch`?** A exceção é propagada para o escopo pai. Se não houver tratamento, ela pode cancelar todo o escopo e suas coroutines filhas. Use `CoroutineExceptionHandler` ou `try/catch` interno para lidar com isso.

**Posso usar `launch` fora de um `CoroutineScope`?** Não. O `launch` é uma função de extensão de `CoroutineScope`. Você precisa de um escopo como `runBlocking`, `viewModelScope`, `lifecycleScope` ou um `CoroutineScope` customizado.

### Termos Relacionados

- [Coroutine](/glossario/coroutine) — o conceito fundamental de concorrência leve em Kotlin
- [Suspend](/glossario/suspend) — funções que podem ser pausadas e retomadas dentro de coroutines
- [Async](/glossario/async) — coroutine builder que retorna um resultado via `Deferred`
- [Flow](/glossario/flow) — streams assíncronos reativos baseados em coroutines

`launch` é provavelmente o coroutine builder que você mais vai usar no dia a dia.
