Android WorkManager em 2026: Tarefas em Segundo Plano, Restrições e Perguntas de Entrevista
Guia completo sobre WorkManager para Android em 2026: criação de Workers, restrições de execução, encadeamento de tarefas e perguntas técnicas de entrevista.

WorkManager representa a solução oficial do Jetpack para executar tarefas em segundo plano garantidas no Android. Diferentemente das threads convencionais ou corrotinas que desaparecem quando o processo do aplicativo termina, o WorkManager persiste os trabalhos agendados e os executa mesmo após a reinicialização do dispositivo. A versão 2.11.2 (estável, março de 2026) suporta API 23+ e seleciona automaticamente o mecanismo subjacente ideal (JobScheduler, AlarmManager) conforme a versão Android do dispositivo.
WorkManager é ideal para tarefas adiáveis que requerem execução garantida: sincronização de dados, upload de arquivos, processamento de imagens. Para operações imediatas sem garantia de sobrevivência ao processo, as corrotinas do Kotlin continuam sendo preferíveis.
Configuração do WorkManager 2.11 em um Projeto Kotlin
A integração do WorkManager começa adicionando a dependência no arquivo Gradle. A versão 2.11+ requer minSdk 23 e compileSdk 33 como mínimo.
dependencies {
val workVersion = "2.11.2"
implementation("androidx.work:work-runtime-ktx:$workVersion")
// Opcional: para testes
androidTestImplementation("androidx.work:work-testing:$workVersion")
}O artefato work-runtime-ktx inclui extensões Kotlin e suporte a corrotinas através do CoroutineWorker. O WorkManager se inicializa automaticamente por meio de um ContentProvider declarado no manifesto da biblioteca.
Criação de um Worker Simples com doWork()
Uma classe Worker herda da classe base e sobrescreve o método doWork(). O sistema executa esse método em uma thread de segundo plano dedicada.
class SyncWorker(
context: Context,
params: WorkerParameters
) : Worker(context, params) {
override fun doWork(): Result {
// Leitura dos dados de entrada
val userId = inputData.getString("user_id") ?: return Result.failure()
return try {
// Execução da sincronização
val syncService = SyncService.getInstance(applicationContext)
syncService.syncUserData(userId)
Result.success()
} catch (e: IOException) {
// Tentar novamente em caso de erro de rede
Result.retry()
} catch (e: Exception) {
// Falha permanente
Result.failure()
}
}
}Existem três resultados possíveis: Result.success() indica conclusão bem-sucedida, Result.failure() interrompe as novas tentativas, e Result.retry() reagenda conforme a política de backoff configurada.
Uso do CoroutineWorker para Funções Suspend
Quando o trabalho envolve funções suspend (chamadas Retrofit, consultas Room), o CoroutineWorker simplifica consideravelmente o código eliminando callbacks aninhados.
class UploadWorker(
context: Context,
params: WorkerParameters
) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
val imageUri = inputData.getString("image_uri")
?: return Result.failure()
// Relatório de progresso (visível nos observadores de WorkInfo)
setProgress(workDataOf("status" to "comprimindo"))
val compressed = ImageCompressor.compress(imageUri)
setProgress(workDataOf("status" to "enviando"))
return try {
val api = RetrofitClient.uploadService
api.uploadImage(compressed)
Result.success()
} catch (e: HttpException) {
if (e.code() in 500..599) Result.retry()
else Result.failure()
}
}
}O método setProgress() permite comunicar o estado de progresso aos observadores da interface do usuário, particularmente útil para operações longas como upload de arquivos grandes.
Definição de Restrições de Execução
As restrições permitem especificar as condições necessárias para a execução do trabalho. O WorkManager aguarda até que todas as restrições sejam satisfeitas antes de iniciar o Worker.
// Restrições para sincronização de dados
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresBatteryNotLow(true)
.setRequiresStorageNotLow(true)
.build()
val syncRequest = OneTimeWorkRequestBuilder<SyncWorker>()
.setConstraints(constraints)
.setInputData(workDataOf("user_id" to userId))
.build()
WorkManager.getInstance(context).enqueue(syncRequest)As restrições disponíveis incluem o tipo de rede (CONNECTED, UNMETERED, METERED, NOT_ROAMING), o estado da bateria, o armazenamento disponível e o estado de carregamento do dispositivo. No Android 7+, a restrição setRequiresDeviceIdle(true) permite aguardar até que o dispositivo esteja inativo.
Configuração de Políticas de Backoff
Quando um Worker retorna Result.retry(), o WorkManager reagenda automaticamente a execução conforme uma política de backoff configurável.
val uploadRequest = OneTimeWorkRequestBuilder<UploadWorker>()
.setBackoffCriteria(
BackoffPolicy.EXPONENTIAL,
WorkRequest.MIN_BACKOFF_MILLIS,
TimeUnit.MILLISECONDS
)
.build()Existem duas políticas disponíveis: LINEAR (atraso constante entre tentativas) e EXPONENTIAL (atraso que dobra a cada tentativa). O atraso mínimo é de 10 segundos, e o máximo atinge 5 horas.
Encadeamento de Trabalhos Sequenciais e Paralelos
O WorkManager permite criar fluxos de trabalho complexos encadeando múltiplos Workers. Os trabalhos podem ser executados sequencial ou paralelamente.
// Fluxo: compressão -> upload -> notificação
val compressWork = OneTimeWorkRequestBuilder<CompressWorker>().build()
val uploadWork = OneTimeWorkRequestBuilder<UploadWorker>().build()
val notifyWork = OneTimeWorkRequestBuilder<NotificationWorker>().build()
WorkManager.getInstance(context)
.beginWith(compressWork)
.then(uploadWork)
.then(notifyWork)
.enqueue()Para execução paralela, o método beginWith() aceita uma lista de WorkRequests:
// Download paralelo de múltiplos recursos
val downloads = listOf(
OneTimeWorkRequestBuilder<DownloadWorker>()
.setInputData(workDataOf("url" to url1)).build(),
OneTimeWorkRequestBuilder<DownloadWorker>()
.setInputData(workDataOf("url" to url2)).build(),
OneTimeWorkRequestBuilder<DownloadWorker>()
.setInputData(workDataOf("url" to url3)).build()
)
val mergeWork = OneTimeWorkRequestBuilder<MergeWorker>().build()
WorkManager.getInstance(context)
.beginWith(downloads)
.then(mergeWork)
.enqueue()Trabalhos Únicos e Estratégias de Substituição
Os trabalhos únicos garantem que apenas uma instância de um trabalho particular exista na fila, evitando duplicações durante chamadas repetidas.
val syncRequest = OneTimeWorkRequestBuilder<SyncWorker>().build()
WorkManager.getInstance(context).enqueueUniqueWork(
"user_sync",
ExistingWorkPolicy.REPLACE,
syncRequest
)Existem três políticas: REPLACE cancela o trabalho existente e o substitui, KEEP mantém o trabalho existente e ignora o novo, APPEND adiciona o novo trabalho à cadeia existente.
Trabalhos Periódicos com PeriodicWorkRequest
Para tarefas recorrentes como sincronização de dados ou limpeza de cache, o PeriodicWorkRequest oferece agendamento automático.
val periodicSync = PeriodicWorkRequestBuilder<SyncWorker>(
repeatInterval = 1,
repeatIntervalTimeUnit = TimeUnit.HOURS,
flexTimeInterval = 15,
flexTimeIntervalUnit = TimeUnit.MINUTES
)
.setConstraints(constraints)
.build()
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
"periodic_sync",
ExistingPeriodicWorkPolicy.UPDATE,
periodicSync
)O intervalo mínimo é de 15 minutos. O parâmetro flexTimeInterval define uma janela durante a qual o trabalho pode ser executado, permitindo que o sistema otimize o consumo de bateria.
Observação do Estado dos Trabalhos
A observação dos trabalhos permite atualizar a interface do usuário conforme o progresso e o resultado.
// Em um ViewModel
val workInfo: LiveData<WorkInfo> = WorkManager
.getInstance(application)
.getWorkInfoByIdLiveData(uploadRequest.id)
// Observação em um Fragment
viewModel.workInfo.observe(viewLifecycleOwner) { info ->
when (info.state) {
WorkInfo.State.RUNNING -> {
val progress = info.progress.getString("status")
updateProgressUI(progress)
}
WorkInfo.State.SUCCEEDED -> showSuccessUI()
WorkInfo.State.FAILED -> showErrorUI()
else -> { /* Em espera ou cancelado */ }
}
}Pronto para mandar bem nas entrevistas de Android?
Pratique com nossos simuladores interativos, flashcards e testes tecnicos.
Perguntas de Entrevista Técnica sobre WorkManager
As entrevistas técnicas de Android frequentemente abordam o WorkManager. A seguir, as perguntas mais comuns com suas respostas detalhadas.
Qual é a diferença entre Worker e CoroutineWorker?
Worker executa doWork() em uma thread de segundo plano de forma síncrona. CoroutineWorker permite utilizar funções suspend e é executado por padrão em Dispatchers.Default. Para operações assíncronas envolvendo chamadas de rede ou acessos a banco de dados com Room, o CoroutineWorker é preferível.
Como o WorkManager garante a execução dos trabalhos?
O WorkManager persiste as informações de trabalho em um banco de dados SQLite interno. Ao iniciar o aplicativo ou durante a inicialização do dispositivo (se a permissão RECEIVE_BOOT_COMPLETED estiver concedida), o WorkManager restaura os trabalhos pendentes e os reagenda.
Qual é a duração máxima de execução de um Worker?
Um Worker dispõe de no máximo 10 minutos para completar seu trabalho na maioria dos dispositivos. Esse tempo pode variar conforme os fabricantes e as otimizações de bateria. Para trabalhos longos, deve-se utilizar setForeground() com uma notificação em primeiro plano.
Como transmitir dados entre Workers encadeados?
O Worker que termina pode retornar dados através de Result.success(outputData). O próximo Worker na cadeia acessa esses dados via inputData. Para cadeias paralelas que convergem para um único Worker, um InputMerger combina as saídas.
override fun doWork(): Result {
val processedId = processData()
val output = workDataOf("processed_id" to processedId)
return Result.success(output)
}Como testar um Worker?
A biblioteca work-testing fornece TestListenableWorkerBuilder para testes unitários e WorkManagerTestInitHelper para testes de integração.
@Test
fun testSyncWorker() = runTest {
val context = ApplicationProvider.getApplicationContext<Context>()
val worker = TestListenableWorkerBuilder<SyncWorker>(context)
.setInputData(workDataOf("user_id" to "123"))
.build()
val result = worker.doWork()
assertThat(result).isEqualTo(ListenableWorker.Result.success())
}Conclusão
O WorkManager constitui a base fundamental da gestão de tarefas em segundo plano no Android moderno. Sua capacidade de persistir trabalhos, respeitar restrições do sistema e se adaptar às diferentes versões do Android o torna uma ferramenta indispensável. O domínio dos conceitos de restrições, encadeamento e políticas de backoff permite construir aplicativos robustos capazes de gerenciar eficientemente operações assíncronas complexas, mesmo em condições de rede ou energia desfavoráveis.
Você saberia encontrar o bug em Android?
Um trecho real, um bug escondido, uma tentativa por dia. Sem conta para testar.

Escrito por
Anthony Fillion-MailletFundador da SharpSkill
Desenvolvedor fullstack há mais de 10 anos. Dirige a SharpSkill e responde por tudo o que é publicado aqui.
Atualizado em 22 de agosto de 2026
Tags
Compartilhar
Artigos relacionados

Modularização Android em 2026: Arquitetura Multi-Módulo e Perguntas de Entrevista
Guia completo sobre modularização Android em 2026. Aprenda a estruturar uma arquitetura multi-módulo, usar catálogos de versões Gradle e dominar as perguntas essenciais de entrevista técnica.

Kotlin Flow vs StateFlow vs SharedFlow: perguntas de entrevista Android em 2026
As perguntas sobre Kotlin Flow vs StateFlow vs SharedFlow que os entrevistadores de Android fazem em 2026, com respostas claras, tabela comparativa e código pronto para produção.

Android 16 em 2026: Novas APIs, Desktop Mode e Perguntas de Entrevista
Análise aprofundada do Android 16 API 36: edge-to-edge obrigatório, Desktop Mode, ProgressStyle, navegação preditiva e perguntas de entrevista técnica para desenvolvedores Android em 2026.