Atualizar um trabalho que já está na fila

O WorkManager permite que você atualize um WorkRequest depois de colocá-lo na fila. Isso geralmente é necessário em apps maiores que mudam com frequência. ou que precisem atualizar os workers em tempo real. A partir do WorkManager versão 2.8.0, a API updateWork() é a maneira de fazer isso.

O método updateWork() permite mudar certos aspectos de uma WorkRequest imediatamente, sem precisar passar pelo processo de manualmente cancelando e enfileirando um novo. Isso simplifica muito o desenvolvimento de desenvolvimento de software.

Evite cancelar um trabalho

Em geral, evite cancelar um WorkRequest existente e enfileirar um novo um. Isso pode fazer com que o app repita determinadas tarefas, e pode exigir que você a escrever uma quantidade significativa de código adicional.

Considere os seguintes exemplos de onde o cancelamento de uma WorkRequest pode fazer dificuldades:

  • Solicitação de back-end:se você cancelar um Worker durante o processamento. um payload para enviar ao servidor, o novo Worker precisa ser reiniciado e recalcular o payload potencialmente caro.
  • Agendamento:se você cancelar um PeriodicWorkRequest e fizer como o novo PeriodicWorkRequest para ser executado no mesmo cronograma, você precisa para calcular um ajuste de horário e garantir que o novo tempo de execução esteja alinhado com a solicitação de trabalho anterior.

A API updateWork() permite atualizar as restrições de uma solicitação de trabalho e outros parâmetros sem precisar cancelar e enfileirar uma nova solicitação.

Quando cancelar um trabalho

Há casos em que é necessário cancelar um WorkRequest diretamente em vez de chame updateWork(). Isso é o que você deve fazer quando quiser alterar o fundamental do trabalho que você colocou na fila.

Quando atualizar o endereço do trabalho

Imagine um aplicativo de fotos que faz um backup diário das fotos do usuário. Ele tem colocou um PeriodicWorkRequest na fila para fazer isso. O WorkRequest tem restrições que exigem que o dispositivo esteja carregando e conectado a uma rede Wi-Fi.

No entanto, o usuário carrega o dispositivo somente por 20 minutos por dia usando um carregador. Nesse caso, o app pode querer atualizar a WorkRequest para relaxar o de carregamento do dispositivo. Assim, ainda será possível fazer upload das fotos mesmo se o dispositivo não está totalmente carregada.

Nessa situação, use o método updateWork() para atualizar o trabalho. restrições da solicitação.

Como atualizar o endereço do trabalho

O método updateWork() fornece uma maneira simples de atualizar um WorkRequest, sem precisar cancelar e colocar um novo na fila.

Para usar trabalhos de atualização na fila, siga estas etapas:

  1. Consiga o ID atual para o trabalho na fila: receba o ID da WorkRequest que você gostaria de atualizar. Você pode recuperar esse ID com qualquer getWorkInfo ou pela persistência manual do ID desde o WorkRequest para recuperação posterior com a propriedade pública WorkRequest.id, antes de colocá-lo na fila.
  2. Criar um novo WorkRequest: crie um novo WorkRequest e use WorkRequest.Builder.setID() para definir o ID para corresponder ao ID do modelo WorkRequest
  3. Defina restrições: use WorkRequest.Builder.setConstraints() para transmitir o Novas restrições do WorkManager.
  4. Chame updateWork: transmita o novo WorkRequest para updateWork().

Atualizar exemplo de trabalho

Aqui está um exemplo de snippet de código em Kotlin que demonstra como usar a Método updateWork() para mudar as restrições de bateria de um WorkRequest usado. para enviar fotos:

suspend fun updatePhotoUploadWork() {
    // Get instance of WorkManager.
    val workManager = WorkManager.getInstance(context)

    // Retrieve the work request ID. In this example, the work being updated is unique
    // work so we can retrieve the ID using the unique work name.
    val photoUploadWorkInfoList = workManager.getWorkInfosForUniqueWork(
        PHOTO_UPLOAD_WORK_NAME
    ).await()

    val existingWorkRequestId = photoUploadWorkInfoList.firstOrNull()?.id ?: return

    // Update the constraints of the WorkRequest to not require a charging device.
    val newConstraints = Constraints.Builder()
        // Add other constraints as required here.
        .setRequiresCharging(false)
        .build()

    // Create new WorkRequest from existing Worker, new constraints, and the id of the old WorkRequest.
    val updatedWorkRequest: WorkRequest =
        OneTimeWorkRequestBuilder<MyWorker>()
            .setConstraints(newConstraints)
            .setId(existingWorkRequestId)
            .build()

    // Pass the new WorkRequest to updateWork().
    workManager.updateWork(updatedWorkRequest)
}

Gerenciar o resultado

updateWork() retorna um ListenableFuture<UpdateResult>. O UpdateResult pode ter um dos vários valores que descrevem se O WorkManager conseguiu aplicar as mudanças. Ela também indica quando foi possível para aplicar a alteração.

Para saber mais, consulte updateWork() e UpdateResult referência.

Acompanhe o trabalho de várias gerações

Cada vez que você atualiza uma WorkRequest, a geração dela aumenta em um. Isso permite rastrear exatamente qual WorkRequest está na fila. As gerações oferecem mais controle ao observar, rastrear e testar trabalhos solicitações.

Para gerar a geração de um WorkRequest, siga estas etapas:

  1. WorkInfo: chame WorkManager.getWorkInfoById() para recuperar uma instância. de WorkInfo correspondente ao seu WorkRequest.
  2. getGeneration: chame getGeneration() na instância de WorkInfo. A Int retornada corresponde à geração do WorkRequest.
    • Não há um campo ou propriedade de geração, apenas o WorkInfo.getGeneration().

Exemplo de geração de faixas

Veja a seguir um exemplo de implementação do fluxo de trabalho descrito acima para recuperar a geração de um WorkRequest.

// Get instance of WorkManager.
val workManager = WorkManager.getInstance(context)

// Retrieve WorkInfo instance.
val workInfo = workManager.getWorkInfoById(oldWorkRequestId)

// Call getGeneration to retrieve the generation.
val generation = workInfo.getGeneration()

Políticas para atualizar o trabalho

Anteriormente, a solução recomendada para atualizar o trabalho periódico era enfileirar um PeriodicWorkRequest pela política ExistingPeriodicWorkPolicy.REPLACE. Se houvesse um PeriodicWorkRequest pendente com o mesmo id exclusivo, o novo de trabalho seria cancelada e excluída. Esta política foi suspensa em para o fluxo de trabalho usando ExistingPeriodicWorkPolicy.UPDATE.

Por exemplo, ao usar enqueueUniquePeriodicWork com uma PeriodicWorkRequest, é possível inicializar o novo PeriodicWorkRequest com o política ExistingPeriodicWorkPolicy.UPDATE. Se houver PeriodicWorkRequest com o mesmo nome exclusivo, o WorkManager o atualiza para a nova especificação. Seguindo esse fluxo de trabalho, não é necessário usar updateWork():