WorkManager ti consente di creare e mettere in coda una catena di lavoro che specifica più attività dipendenti e definisce l'ordine in cui devono essere eseguite. Questa funzionalità è particolarmente utile quando devi eseguire diverse attività in un ordine particolare.
Per creare una catena di lavoro, puoi utilizzare
WorkManager.beginWith(OneTimeWorkRequest)
o
WorkManager.beginWith(List<OneTimeWorkRequest>)
, che restituiscono ciascuna un'istanza di
WorkContinuation
.
È quindi possibile utilizzare un WorkContinuation
per aggiungere un OneTimeWorkRequest
dipendente
di Compute Engine utilizzando
then(OneTimeWorkRequest)
:
o
then(List<OneTimeWorkRequest>)
di Google.
Ogni chiamata di WorkContinuation.then(...)
restituisce una nuova istanza di WorkContinuation
. Se aggiungi un List
di OneTimeWorkRequest
istanze, queste richieste possono essere eseguite in parallelo.
Infine, puoi utilizzare
WorkContinuation.enqueue()
per enqueue()
la tua catena di WorkContinuation
.
Vediamo un esempio. In questo esempio, tre diversi job worker sono configurate per l'esecuzione (potenzialmente in parallelo). I risultati di questi worker vengono poi uniti e trasmessi a un job worker con cache. Infine, l'output il job viene passato a un worker di caricamento, che carica i risultati su o server web.
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();
Fusioni di input
Quando concateni OneTimeWorkRequest
istanze, l'output del lavoro padre
inviate come input ai publisher secondari. Pertanto, nell'esempio precedente, gli output di plantName1
, plantName2
e plantName3
verrebbero passati come input alla richiesta cache
.
Per gestire gli input di più richieste di lavoro principali, WorkManager utilizza
InputMerger
.
Esistono due tipi diversi di InputMerger
forniti da WorkManager:
OverwritingInputMerger
tenta di aggiungere tutte le chiavi da tutti gli input all'output. In caso di conflitti, sovrascriverà le chiavi impostate in precedenza.ArrayCreatingInputMerger
tenta di unire gli input, creando array se necessario.
Se hai un caso d'uso più specifico, puoi crearne uno tuo sottoclassificando
InputMerger
.
OverwritingInputMerger
OverwritingInputMerger
è il metodo di unione predefinito. Se esistono conflitti di chiavi nella combinazione, l'ultimo valore di una chiave sovrascriverà eventuali versioni precedenti nei dati di output risultanti.
Ad esempio, se gli input della pianta hanno ciascuno una chiave corrispondente ai rispettivi nomi di variabile ("plantName1"
, "plantName2"
e "plantName3"
), i dati passati al worker cache
avranno tre coppie chiave-valore.
In caso di conflitto, "vince" l'ultimo worker completato e il relativo valore viene passato a cache
.
Poiché le richieste di lavoro vengono eseguite in parallelo, non hai alcuna garanzia sull'ordine di esecuzione. Nell'esempio precedente, plantName1
potrebbe contenere un valore "tulip"
o "elm"
, a seconda del valore scritto per ultimo. Se esiste la possibilità che si verifichi un conflitto di chiavi e devi conservare tutti gli output
in una fusione, ArrayCreatingInputMerger
potrebbe essere un'opzione migliore.
ArrayCreatingInputMerger
Per l'esempio precedente, dato che vogliamo conservare gli output di tutti i worker con nome pianta, dobbiamo utilizzare un 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
accoppia ogni chiave a un array. Se ciascuna delle chiavi è univoca, il risultato è una serie di array di un elemento.
In caso di collisioni di chiavi, tutti i valori corrispondenti vengono raggruppati in un array.
Stati di chaining e di lavoro
Le catene di OneTimeWorkRequest
vengono eseguite in sequenza fintanto che il loro lavoro
viene completata correttamente (restituisce un Result.success()
). Lavoro
potrebbero non riuscire o essere annullate durante l'esecuzione, il che ha effetti downstream sulle
e richieste di lavoro dipendenti.
Quando il primo OneTimeWorkRequest
viene inserito in coda in una catena di richieste di lavoro, tutte le richieste di lavoro successive vengono bloccate fino al completamento del lavoro della prima richiesta di lavoro.
Una volta inserita in coda e soddisfatti tutti i vincoli di lavoro, inizia l'esecuzione della prima richiesta di lavoro. Se le operazioni vengono completate correttamente nella
OneTimeWorkRequest
o List<OneTimeWorkRequest>
(ovvero, restituisce un
Result.success()
), il prossimo insieme di richieste di lavoro dipendenti sarà
in coda.
Se ogni richiesta di lavoro viene completata correttamente, lo stesso pattern si propaga nel resto della catena di richieste di lavoro fino al completamento di tutto il lavoro nella catena. Sebbene questo sia il caso più semplice e spesso preferito, sono altrettanto importanti.
Quando si verifica un errore mentre un lavoratore elabora la tua richiesta di lavoro, puoi: riprova a eseguire la richiesta in base a un criterio di backoff che hai definire. Se viene eseguito un nuovo tentativo per una richiesta che fa parte di una catena, verrà eseguito il nuovo tentativo solo per quella richiesta con i dati di input forniti. Qualsiasi lavoro eseguito in parallelo non sarà interessato.
Per ulteriori informazioni sulla definizione di strategie personalizzate per i nuovi tentativi, consulta Ripetere e backoff Norme.
Se il criterio per i nuovi tentativi non è definito o esaurito oppure se raggiungi comunque
in cui OneTimeWorkRequest
restituisce Result.failure()
,
richiesta di lavoro e tutte le richieste di lavoro dipendenti sono contrassegnate come FAILED.
La stessa logica si applica quando un OneTimeWorkRequest
viene annullato. Anche le richieste di lavoro dipendenti sono contrassegnate da CANCELLED
e il relativo lavoro non verrà eseguito.
Tieni presente che se aggiungi altre richieste di lavoro a una catena non riuscita o
ha annullato le richieste di lavoro, anche la richiesta di lavoro appena aggiunta verrà
contrassegnati rispettivamente con FAILED
o CANCELLED
. Se vuoi estendere il lavoro
di una catena esistente, consulta APPEND_OR_REPLACE
in
ExistingWorkPolicy.
Quando crei catene di richieste di lavoro, le richieste di lavoro dipendenti devono definire le regole di ripetizione per garantire che il lavoro venga sempre completato in modo tempestivo. Le richieste di lavoro non riuscite potrebbero comportare catene incomplete e/o stati imprevisti.
Per ulteriori informazioni, consulta la sezione Annullare e interrompere il lavoro.