Exemplos de Código: Capítulo 17 — Background Tasks com WorkManager

Especialização em Mobile Nativo com Android • Demonstrações Práticas Compiláveis


💻 Código de Demonstração: CoroutineWorker, Restrições de Sistema e Agendamento Resiliente

O código abaixo demonstra o agendamento de tarefas em segundo plano confiáveis e com baixo consumo de bateria no Android:

  1. Implementação de CoroutineWorker executando em contexto seguro com suspensão nativa.
  2. Definição de restrições operacionais (Constraints): conexão Wi-Fi ativa, bateria acima do nível crítico e dispositivo em repouso.
  3. Agendamento pontual (OneTimeWorkRequest) e periódico (PeriodicWorkRequest) via WorkManager.
package br.com.portal.mobile.android.cap17

// =====================================================================
// 1. Definição do Worker com Coroutines
// =====================================================================
/*
import android.content.Context
import androidx.work.Constraints
import androidx.work.CoroutineWorker
import androidx.work.NetworkType
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.WorkerParameters
import androidx.work.workDataOf
import java.util.concurrent.TimeUnit
import kotlinx.coroutines.delay

class SincronizacaoDadosWorker(
    appContext: Context,
    workerParams: WorkerParameters
) : CoroutineWorker(appContext, workerParams) {

    override suspend fun doWork(): Result {
        return try {
            // Obtém parâmetros de entrada passados ao agendar o worker
            val urlSincronizacao = inputData.getString("CHAVE_URL") ?: "https://api.portal.com/sync"
            
            // Simula download de dados e sincronização com banco local Room
            delay(2000)

            // Retorna dados de saída opcionais
            val dadosSaida = workDataOf("ITENS_PROCESSADOS" to 42)
            Result.success(dadosSaida)
        } catch (ex: Exception) {
            // Em caso de erro temporário de rede, o WorkManager reagenda automaticamente
            // aplicando Exponential Backoff para poupar energia da bateria
            Result.retry()
        }
    }
}
*/

// =====================================================================
// 2. Orquestrador de Agendamento (Service / UseCase)
// =====================================================================

class GerenciadorSincronizacao(
    // private val workManager: WorkManager
) {
    /*
    fun agendarSincronizacaoResiliente() {
        // Restrições de Hardware e Conectividade
        val restricoes = Constraints.Builder()
            .setRequiredNetworkType(NetworkType.UNMETERED) // Somente em Wi-Fi (sem consumir 4G/5G)
            .setRequiresBatteryNotLow(true)               // Bateria com carga segura
            .setRequiresCharging(false)
            .build()

        // Requisição de Trabalho Único com Backoff Exponencial
        val requisicao = OneTimeWorkRequestBuilder<SincronizacaoDadosWorker>()
            .setConstraints(restricoes)
            .setInputData(workDataOf("CHAVE_URL" to "https://api.portal.com/v1/sync/delta"))
            .setBackoffCriteria(
                androidx.work.BackoffPolicy.EXPONENTIAL,
                15, TimeUnit.MINUTES
            )
            .build()

        // Enfileira a tarefa no banco SQLite interno do WorkManager no SO
        workManager.enqueue(requisicao)
    }

    fun agendarBackupPeriodico() {
        val requisicaoPeriodica = PeriodicWorkRequestBuilder<SincronizacaoDadosWorker>(
            repeatInterval = 12, TimeUnit.HOURS,
            flexTimeInterval = 30, TimeUnit.MINUTES
        ).build()

        workManager.enqueueUniquePeriodicWork(
            "BACKUP_DIARIO_APP",
            androidx.work.ExistingPeriodicWorkPolicy.KEEP,
            requisicaoPeriodica
        )
    }
    */
}

// =====================================================================
// 3. Simulação de Execução do Mecanismo de Retry e Constraints
// =====================================================================

fun main() {
    println("=== WORKMANAGER: AGENDAMENTO RESILIENTE EM SEGUNDO PLANO ===")
    println("1. Constraints Definidas: Wi-Fi Unmetered (Rede Não Medida) + Bateria OK")
    println("2. Política de Retry: Exponential Backoff (15min -> 30min -> 1h)")
    println("3. Sobrevivência: Garantida pelo SO mesmo se o aplicativo for fechado")
    println("Status: Worker configurado e pronto para execução no Android Runtime.")
}