Escopos no Kotlin: Controlando Ciclo de Vida e Cancelamento de Corrotinas

1 – Introdução Gerenciar o ciclo de vida de corrotinas é um dos aspectos mais importantes da programação assíncrona no Kotlin. Para isso, o Kotlin oferece escopos: estruturas que ajudam a controlar como e quando corrotinas são executadas, além de facilitar o cancelamento de tarefas quando necessário. Neste artigo, exploraremos os principais tipos de escopos no Kotlin e suas diferenças. Você verá como escolher o escopo certo pode simplificar o gerenciamento de corrotinas no seu código. 2 – O Que São Escopos? Escopos no Kotlin são "gestores" do ciclo de vida das corrotinas. Eles: Determinam onde e como as corrotinas serão executadas. Controlam o ciclo de vida das corrotinas, incluindo seu cancelamento. Tipos de Escopos: Escopos baseados em classes: Utilizados para operações de longo prazo ou associadas a componentes específicos, como viewModelScope em Android. Escopos baseados em funções: Utilizados para operações temporárias e locais, como coroutineScope e supervisorScope. 3 – Escopos Baseados em Classes 3.1 – CoroutineScope O que é? É a interface base para criar escopos personalizados. Você pode associar um CoroutineScope a um contexto específico (por exemplo, um Dispatcher) para gerenciar corrotinas. Quando usar? Para criar escopos customizados que controlam o ciclo de vida de várias corrotinas. Exemplo: import kotlinx.coroutines.* fun main() { val customScope = CoroutineScope(Dispatchers.Default) customScope.launch { println("Executando dentro do CoroutineScope: ${Thread.currentThread().name}") } } 3.2 – viewModelScope O que é? Um escopo especial fornecido pela biblioteca Android Jetpack, projetado para o ciclo de vida de ViewModels. Quando o ViewModel é destruído, todas as corrotinas associadas ao viewModelScope são automaticamente canceladas. Quando usar? Para gerenciar corrotinas associadas à UI no Android. Exemplo: import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import kotlinx.coroutines.launch class MyViewModel : ViewModel() { fun loadData() { viewModelScope.launch { println("Carregando dados na thread: ${Thread.currentThread().name}") } } } 3.3 – backgroundScope O que é? Um escopo projetado para operações de longo prazo que podem continuar mesmo se o ciclo de vida do componente principal terminar. Quando usar? Para tarefas que precisam persistir além do ciclo de vida imediato, como sincronização em segundo plano. Exemplo: import kotlinx.coroutines.* fun main() { val backgroundScope = CoroutineScope(Dispatchers.IO) backgroundScope.launch { println("Executando no background: ${Thread.currentThread().name}") } } 4 – Escopos Baseados em Funções 4.1 – coroutineScope O que é? Uma função suspensa que cria um escopo temporário. Todas as corrotinas dentro de um coroutineScope compartilham o mesmo Job. Quando usar? Para garantir que todas as tarefas dentro de um bloco sejam concluídas ou canceladas em conjunto. Exemplo: import kotlinx.coroutines.* suspend fun main() { coroutineScope { launch { println("Corrotina 1 executando...") } launch { println("Corrotina 2 executando...") } } println("Todas as corrotinas concluídas.") } 4.2 – supervisorScope O que é? Semelhante ao coroutineScope, mas com uma diferença crucial: falhas em uma corrotina não afetam as outras dentro do escopo. Quando usar? Para garantir que todas as tarefas dentro de um bloco sejam concluídas ou canceladas em conjunto. Exemplo: import kotlinx.coroutines.* suspend fun main() { supervisorScope { launch { println("Corrotina 1 executando...") throw RuntimeException("Erro na Corrotina 1") } launch { println("Corrotina 2 executando...") } } println("SupervisorScope concluído.") } 5 – Comparação: coroutineScope vs. supervisorScope Aspecto coroutineScope supervisorScope Cancelamento Cancela todas as corrotinas em caso de falha. Apenas a corrotina com erro é cancelada. Relacionamento entre tarefas Corrotinas dependentes umas das outras. Corrotinas independentes. Quando usar Quando todas as tarefas precisam ter sucesso. Quando as tarefas podem falhar independentemente. 6 – Conclusão Escopos são ferramentas poderosas no Kotlin para gerenciar o ciclo de vida de corrotinas. Eles ajudam a evitar vazamentos de recursos e facilitam o cancelamento de tarefas desnecessárias. Resumo dos Escopos: CoroutineScope: Para escopos personalizados. viewModelScope: Para gerenciar corrotinas vinculadas a ViewModels no Android. coroutineScope: Para escopos temporários onde todas as tarefas dependem umas das outras. supervisorScope: Para tarefas independentes. No próximo artigo

Feb 27, 2025 - 09:09
 0
Escopos no Kotlin: Controlando Ciclo de Vida e Cancelamento de Corrotinas

1 – Introdução

Gerenciar o ciclo de vida de corrotinas é um dos aspectos mais importantes da programação assíncrona no Kotlin. Para isso, o Kotlin oferece escopos: estruturas que ajudam a controlar como e quando corrotinas são executadas, além de facilitar o cancelamento de tarefas quando necessário.

Neste artigo, exploraremos os principais tipos de escopos no Kotlin e suas diferenças. Você verá como escolher o escopo certo pode simplificar o gerenciamento de corrotinas no seu código.

2 – O Que São Escopos?

Escopos no Kotlin são "gestores" do ciclo de vida das corrotinas. Eles:

  1. Determinam onde e como as corrotinas serão executadas.
  2. Controlam o ciclo de vida das corrotinas, incluindo seu cancelamento.

Tipos de Escopos:

  1. Escopos baseados em classes: Utilizados para operações de longo prazo ou associadas a componentes específicos, como viewModelScope em Android.
  2. Escopos baseados em funções: Utilizados para operações temporárias e locais, como coroutineScope e supervisorScope.

3 – Escopos Baseados em Classes

3.1 – CoroutineScope

  • O que é? É a interface base para criar escopos personalizados. Você pode associar um CoroutineScope a um contexto específico (por exemplo, um Dispatcher) para gerenciar corrotinas.
  • Quando usar? Para criar escopos customizados que controlam o ciclo de vida de várias corrotinas.
  • Exemplo:
import kotlinx.coroutines.*

fun main() {
    val customScope = CoroutineScope(Dispatchers.Default)

    customScope.launch {
        println("Executando dentro do CoroutineScope: ${Thread.currentThread().name}")
    }
}

3.2 – viewModelScope

  • O que é? Um escopo especial fornecido pela biblioteca Android Jetpack, projetado para o ciclo de vida de ViewModels. Quando o ViewModel é destruído, todas as corrotinas associadas ao viewModelScope são automaticamente canceladas.
  • Quando usar?
    Para gerenciar corrotinas associadas à UI no Android.

  • Exemplo:

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch

class MyViewModel : ViewModel() {
    fun loadData() {
        viewModelScope.launch {
            println("Carregando dados na thread: ${Thread.currentThread().name}")
        }
    }
}

3.3 – backgroundScope

  • O que é? Um escopo projetado para operações de longo prazo que podem continuar mesmo se o ciclo de vida do componente principal terminar.
  • Quando usar?
    Para tarefas que precisam persistir além do ciclo de vida imediato, como sincronização em segundo plano.

  • Exemplo:

import kotlinx.coroutines.*

fun main() {
    val backgroundScope = CoroutineScope(Dispatchers.IO)

    backgroundScope.launch {
        println("Executando no background: ${Thread.currentThread().name}")
    }
}

4 – Escopos Baseados em Funções

4.1 – coroutineScope

  • O que é? Uma função suspensa que cria um escopo temporário. Todas as corrotinas dentro de um coroutineScope compartilham o mesmo Job.
  • Quando usar? Para garantir que todas as tarefas dentro de um bloco sejam concluídas ou canceladas em conjunto.
  • Exemplo:
import kotlinx.coroutines.*

suspend fun main() {
    coroutineScope {
        launch {
            println("Corrotina 1 executando...")
        }
        launch {
            println("Corrotina 2 executando...")
        }
    }
    println("Todas as corrotinas concluídas.")
}

4.2 – supervisorScope

  • O que é? Semelhante ao coroutineScope, mas com uma diferença crucial: falhas em uma corrotina não afetam as outras dentro do escopo.
  • Quando usar? Para garantir que todas as tarefas dentro de um bloco sejam concluídas ou canceladas em conjunto.
  • Exemplo:
import kotlinx.coroutines.*

suspend fun main() {
    supervisorScope {
        launch {
            println("Corrotina 1 executando...")
            throw RuntimeException("Erro na Corrotina 1")
        }
        launch {
            println("Corrotina 2 executando...")
        }
    }
    println("SupervisorScope concluído.")
}

5 – Comparação: coroutineScope vs. supervisorScope

Aspecto coroutineScope supervisorScope
Cancelamento Cancela todas as corrotinas em caso de falha. Apenas a corrotina com erro é cancelada.
Relacionamento entre tarefas Corrotinas dependentes umas das outras. Corrotinas independentes.
Quando usar Quando todas as tarefas precisam ter sucesso. Quando as tarefas podem falhar independentemente.

6 – Conclusão

Escopos são ferramentas poderosas no Kotlin para gerenciar o ciclo de vida de corrotinas. Eles ajudam a evitar vazamentos de recursos e facilitam o cancelamento de tarefas desnecessárias.

Resumo dos Escopos:

  1. CoroutineScope: Para escopos personalizados.
  2. viewModelScope: Para gerenciar corrotinas vinculadas a ViewModels no Android.
  3. coroutineScope: Para escopos temporários onde todas as tarefas dependem umas das outras.
  4. supervisorScope: Para tarefas independentes. No próximo artigo, exploraremos os métodos utilitários e métodos de execução que você pode usar para otimizar ainda mais suas corrotinas.

Referência
Documentação oficial do Kotlin sobre corrotinas