O WorkManager permite que você crie e coloque em fila uma cadeira de trabalho que especifica várias tarefas dependentes e define a ordem em que elas serão executadas. Essa funcionalidade é particularmente útil quando você precisa executar várias tarefas em uma ordem específica.
Para criar uma cadeia de trabalhos, use
WorkManager.beginWith(OneTimeWorkRequest)
ou
WorkManager.beginWith(List<OneTimeWorkRequest>)
,
que retornam um instância de
WorkContinuation
.
Um WorkContinuation
pode ser usado para adicionar instâncias de OneTimeWorkRequest
dependentes usando
then(OneTimeWorkRequest)
ou
then(List<OneTimeWorkRequest>)
Toda invocação de WorkContinuation.then(...)
retorna uma novainstância de WorkContinuation
. Se você adicionar uma List
de instâncias de OneTimeWorkRequest
, essas solicitações poderão ser executadas em paralelo.
Por fim, use o método
WorkContinuation.enqueue()
para enqueue()
(enfileirar) sua cadeia de WorkContinuation
s.
Veja um exemplo. Neste exemplo, três jobs diferentes do worker estão configurados para serem executados (possivelmente em paralelo). Em seguida, os resultados desses workers serão unidos e transmitidos para um job de armazenamento em cache. Por fim, a saída desse job será transmitida para um worker de upload, que fará upload dos resultados para um servidor remoto.
Kotlin
WorkManager.getInstance(myContext) // Candidates to run in parallel .beginWith(listOf(plantName1, plantName2, plantName3)) // Dependent work (only runs after all previous work in chain) .then(cache) .then(upload) // Call enqueue to kick things off .enqueue()
Java
WorkManager.getInstance(myContext) // Candidates to run in parallel .beginWith(Arrays.asList(plantName1, plantName2, plantName3)) // Dependent work (only runs after all previous work in chain) .then(cache) .then(upload) // Call enqueue to kick things off .enqueue();
Fusões de entrada
Quando você encadeia instâncias de OneTimeWorkRequest
, a saída das solicitações de
trabalho pai é transmitida como entrada para os filhos. Portanto, no exemplo acima, as
saídas de plantName1
, plantName2
e plantName3
seriam transmitidas como
entradas para a solicitação cache
.
Para gerenciar entradas de várias solicitações de trabalho pai, o WorkManager usa
InputMerger
.
Há dois tipos diferentes de InputMerger
fornecidos pelo WorkManager:
OverwritingInputMerger
tenta adicionar todas as chaves de todas as entradas à saída. Em caso de conflitos, ela substitui todas as chaves definidas anteriormente.ArrayCreatingInputMerger
tenta mesclar as entradas, criando matrizes quando necessário.
Se você tiver um caso de uso mais específico, poderá criar sua própria subclasse
InputMerger
.
OverwritingInputMerger
OverwritingInputMerger
é o método padrão de mesclagem. Se houver conflitos de chave
na combinação, o valor mais recente de uma chave substituirá todas
as versões anteriores nos dados de saída resultantes.
Por exemplo, se as entradas de fábrica tiverem uma chave correspondente aos respectivos
nomes de variáveis ("plantName1"
, "plantName2"
e "plantName3"
), os
dados transmitidos ao worker cache
terão três pares de chave-valor.
Se houver um conflito, o último worker a ser concluído "ganhará", e o valor dele
será transmitido para cache
.
Como as solicitações de trabalho são executadas em paralelo, você não tem garantia da
ordem em que elas são executadas. No exemplo acima, plantName1
pode conter um
valor de "tulip"
ou "elm"
, dependendo de qual valor foi gravado por
último. Se você tiver um conflito de chaves e precisar preservar todos os dados de saída
em uma mesclagem, ArrayCreatingInputMerger
poderá ser uma opção melhor.
ArrayCreatingInputMerger
Para o exemplo acima, como queremos preservar as saídas de todos os workers de nome de
fábrica, é necessário usar uma ArrayCreatingInputMerger
.
Kotlin
val cache: OneTimeWorkRequest = OneTimeWorkRequestBuilder<PlantWorker>() .setInputMerger(ArrayCreatingInputMerger::class) .setConstraints(constraints) .build()
Java
OneTimeWorkRequest cache = new OneTimeWorkRequest.Builder(PlantWorker.class) .setInputMerger(ArrayCreatingInputMerger.class) .setConstraints(constraints) .build();
ArrayCreatingInputMerger
pareia cada chave com uma matriz. Se cada uma das chaves
for exclusiva, o resultado será uma série de matrizes de um elemento.
Se houver colisões de chave, todos os valores correspondentes serão agrupados em uma matriz.
Encadeamento e status de trabalho
As cadeias de OneTimeWorkRequest
são executadas sequencialmente, desde que o trabalho
seja concluído com sucesso (ou seja, desde que retornem um Result.success()
). As solicitações
de trabalho podem falhar ou ser canceladas durante a execução, o que afeta
solicitações de trabalho dependentes.
Quando a primeira OneTimeWorkRequest
é colocada em fila em uma cadeia de solicitações de trabalho,
todas as solicitações de trabalho subsequentes são bloqueadas até que o trabalho da primeira
solicitação seja concluído.
Depois que a primeira solicitação de trabalho for colocada em fila e todas as restrições forem cumpridas, ela
começará a ser executada. Se o trabalho for concluído na raiz
OneTimeWorkRequest
ou List<OneTimeWorkRequest>
(ou seja, se ele retornar um
Result.success()
), o próximo conjunto de solicitações de trabalho dependentes será colocado na
fila.
Desde que cada solicitação de trabalho seja concluída, esse mesmo padrão é propagado pelo restante da cadeia de solicitações até que todos os trabalhos da cadeia sejam concluídos. Embora esse seja o caso mais simples e geralmente o preferido, também é importante resolver os estados de erro.
Quando ocorre um erro no processamento da solicitação de trabalho por um worker, você pode repetir a solicitação de acordo com uma política de espera definida por você. A repetição de uma solicitação que faz parte de uma cadeia significa que apenas essa solicitação será repetida com os dados de entrada fornecidos. Nenhum trabalho em execução em paralelo será afetado.
Para ver mais informações sobre como definir estratégias personalizadas de novas tentativas, consulte Política de nova tentativa e espera.
Se a política de nova tentativa estiver indefinida ou esgotada, ou se você chegar a algum
estado em que uma OneTimeWorkRequest
retorna Result.failure()
, essa
solicitação de trabalho e todas as solicitações dependentes serão marcadas como FAILED.
.
A mesma lógica se aplica quando uma OneTimeWorkRequest
é cancelada. Todas as solicitações
de trabalho dependentes também serão marcadas como CANCELLED
, e o trabalho delas não será executado.
Se você anexar mais solicitações de trabalho a uma cadeia com falha ou
com solicitações de trabalho canceladas, a solicitação recém-anexada também será marcada
como FAILED
ou CANCELLED
, respectivamente. Se você quiser ampliar o trabalho
de uma cadeia existente, consulte APPEND_OR_REPLACE
em
ExistingWorkPolicy.
Durante a criação de cadeias de solicitações de trabalho, as solicitações dependentes precisam definir políticas de novas tentativas para garantir que o trabalho seja sempre concluído em tempo hábil. Solicitações de trabalho com falha podem resultar em cadeias incompletas e/ou estados inesperados.
Para ver mais informações, consulte Como cancelar e interromper trabalhos.