Aufgaben verketten

Mit WorkManager können Sie eine Arbeitskette erstellen und in die Warteschlange einreihen, in der mehrere abhängige Aufgaben festgelegt und in welcher Reihenfolge sie ausgeführt werden. Diese Funktion ist besonders nützlich, wenn Sie mehrere Aufgaben in einer bestimmten Reihenfolge ausführen müssen.

Zum Erstellen einer Arbeitskette können Sie WorkManager.beginWith(OneTimeWorkRequest) oder WorkManager.beginWith(List<OneTimeWorkRequest>) verwenden, die jeweils eine Instanz von WorkContinuation zurückgeben.

Mit einer WorkContinuation können dann abhängige OneTimeWorkRequest-Instanzen mit then(OneTimeWorkRequest) oder then(List<OneTimeWorkRequest>) hinzugefügt werden.

Bei jedem Aufruf von WorkContinuation.then(...) wird eine neue Instanz von WorkContinuation zurückgegeben. Wenn Sie List aus OneTimeWorkRequest Instanzen hinzufügen, können diese Anfragen möglicherweise parallel ausgeführt werden.

Schließlich können Sie die Methode WorkContinuation.enqueue() verwenden, um einen enqueue() Ihrer WorkContinuation-Kette zu erstellen.

Sehen wir uns ein Beispiel an. In diesem Beispiel sind drei verschiedene Worker-Jobs für die Ausführung konfiguriert (möglicherweise parallel). Die Ergebnisse dieser Worker werden dann zusammengeführt und an einen Caching-Worker-Job weitergeleitet. Schließlich wird die Ausgabe dieses Jobs an einen Upload-Worker übergeben, der die Ergebnisse auf einen Remote-Server hochlädt.

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();

Input Mergers

Wenn Sie OneTimeWorkRequest-Instanzen verketten, wird die Ausgabe übergeordneter Arbeitsanfragen als Eingabe an die untergeordneten Elemente übergeben. Im obigen Beispiel würden also die Ausgaben von plantName1, plantName2 und plantName3 als Eingaben an die cache-Anfrage übergeben werden.

Um Eingaben aus mehreren übergeordneten Arbeitsanfragen zu verwalten, verwendet WorkManager InputMerger.

Es gibt zwei verschiedene Arten von InputMerger, die von WorkManager bereitgestellt werden:

  • OverwritingInputMerger versucht, alle Schlüssel aus allen Eingaben der Ausgabe hinzuzufügen. Bei Konflikten werden die zuvor festgelegten Schlüssel überschrieben.

  • ArrayCreatingInputMerger versucht, die Eingaben zusammenzuführen und bei Bedarf Arrays zu erstellen.

Wenn Sie einen spezifischeren Anwendungsfall haben, können Sie Ihren eigenen schreiben, indem Sie von InputMerger abgeleitet werden.

Überschreiben vonInputMerger

OverwritingInputMerger ist die standardmäßige Zusammenführungsmethode. Bei Schlüsselkonflikten bei der Zusammenführung werden alle früheren Versionen in den resultierenden Ausgabedaten durch den neuesten Wert für einen Schlüssel überschrieben.

Wenn die Pflanzeneingaben beispielsweise jeweils einen Schlüssel haben, der den entsprechenden Variablennamen entspricht ("plantName1", "plantName2" und "plantName3"), haben die an den Worker cache übergebenen Daten drei Schlüssel/Wert-Paare.

Diagramm mit drei Jobs, die unterschiedliche Ausgaben an den nächsten Job in der Kette übergeben. Da die drei Ausgaben alle unterschiedliche Schlüssel haben, erhält der nächste Job drei Schlüssel/Wert-Paare.

Bei einem Konflikt gewinnt der letzte Worker, der „gewinnt“, und sein Wert an cache übergeben.

Diagramm mit drei Jobs, die Ausgaben an den nächsten Job in der Kette übergeben. In diesem Fall erzeugen zwei dieser Jobs Ausgaben mit demselben Schlüssel. Infolgedessen erhält der nächste Job zwei Schlüssel/Wert-Paare, wobei eine der in Konflikt stehenden Ausgaben gelöscht wird.

Da Ihre Arbeitsanfragen parallel ausgeführt werden, kann die Reihenfolge, in der sie ausgeführt werden, nicht garantiert werden. Im obigen Beispiel könnte plantName1 einen Wert von "tulip" oder "elm" enthalten, je nachdem, welcher Wert zuletzt geschrieben wird. Wenn die Möglichkeit eines Schlüsselkonflikts besteht und Sie alle Ausgabedaten in einer Zusammenführung beibehalten müssen, ist ArrayCreatingInputMerger möglicherweise die bessere Option.

ArrayCreateInputMerger

Da im obigen Beispiel die Ausgaben aller Anlagennamen Worker erhalten werden sollen, sollten wir ArrayCreatingInputMerger verwenden.

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 paart jeden Schlüssel mit einem Array. Wenn jeder der Schlüssel eindeutig ist, ist das Ergebnis eine Reihe von Arrays mit einem Element.

Diagramm mit drei Jobs, die unterschiedliche Ausgaben an den nächsten Job in der Kette übergeben. Dem nächsten Job werden drei Arrays übergeben, eines für jeden der Ausgabeschlüssel. Jedes Array hat ein einzelnes Element.

Wenn es Schlüsselkonflikte gibt, werden alle entsprechenden Werte in einem Array gruppiert.

Diagramm mit drei Jobs, die Ausgaben an den nächsten Job in der Kette übergeben. In diesem Fall erzeugen zwei dieser Jobs Ausgaben mit demselben Schlüssel. Dem nächsten Job werden zwei Arrays übergeben, eines für jeden Schlüssel. Eines dieser Arrays hat zwei Elemente, da es zwei Ausgaben mit diesem Schlüssel gab.

Verkettung und Arbeitsstatus

OneTimeWorkRequest-Ketten werden nacheinander ausgeführt, solange ihre Arbeit erfolgreich abgeschlossen wird (d. h., sie geben Result.success() zurück). Arbeitsanfragen können während der Ausführung fehlschlagen oder abgebrochen werden. Dies hat nachgelagerte Auswirkungen auf abhängige Arbeitsanfragen.

Wenn die erste OneTimeWorkRequest in eine Kette von Arbeitsanfragen eingereiht wird, werden alle nachfolgenden Arbeitsanfragen blockiert, bis die Arbeit dieser ersten Arbeit abgeschlossen ist.

Diagramm, das eine Kette von Jobs zeigt. Der erste Job wird in die Warteschlange gestellt. Alle aufeinanderfolgenden Jobs werden blockiert, bis der erste abgeschlossen ist.

Sobald sie in die Warteschlange gestellt wurde und alle Arbeitsbeschränkungen erfüllt sind, wird die erste Arbeitsanfrage ausgeführt. Wenn die Arbeit im Stammverzeichnis OneTimeWorkRequest oder List<OneTimeWorkRequest> erfolgreich abgeschlossen wurde (d. h., ein Result.success() zurückgegeben wird), wird der nächste Satz abhängiger Arbeitsanfragen in die Warteschlange gestellt.

Diagramm, das eine Kette von Jobs zeigt. Der erste Job war erfolgreich und seine beiden unmittelbaren Nachfolger werden in die Warteschlange gestellt. Die verbleibenden Jobs werden blockiert, wenn der vorherige Job beendet wurde.

Solange alle Arbeitsanfragen erfolgreich abgeschlossen wurden, wird dieses Muster auch in der übrigen Kette von Arbeitsanfragen so lange angewendet, bis alle Arbeiten in der Kette abgeschlossen sind. Dies ist zwar der einfachste und häufig bevorzugte Fall, aber Fehlerstatus sind genauso wichtig.

Wenn ein Fehler auftritt, während ein Worker Ihre Arbeitsanfrage verarbeitet, können Sie die Anfrage gemäß einer von Ihnen definierten Backoff-Richtlinie wiederholen. Wenn Sie eine Anfrage wiederholen, die Teil einer Kette ist, wird genau diese Anfrage mit den dafür bereitgestellten Eingabedaten wiederholt. Alle parallel ausgeführten Arbeiten sind davon nicht betroffen.

Diagramm, das eine Kette von Jobs zeigt. Einer der Jobs ist fehlgeschlagen, es wurde jedoch eine Backoff-Richtlinie definiert. Dieser Job wird nach Ablauf der entsprechenden Zeit noch einmal ausgeführt. Die nachfolgenden Jobs in der Kette werden blockiert, bis sie erfolgreich ausgeführt werden.

Weitere Informationen zum Definieren von benutzerdefinierten Wiederholungsstrategien finden Sie unter Wiederholungs- und Backoff-Richtlinie.

Wenn diese Wiederholungsrichtlinie nicht definiert oder ausgeschöpft ist oder Sie einen anderen Status erreichen, in dem ein OneTimeWorkRequest Result.failure() zurückgibt, werden diese Arbeitsanfrage und alle abhängigen Arbeitsanfragen als FAILED. markiert.

Diagramm, das eine Kette von Jobs zeigt. Ein Job ist fehlgeschlagen und kann nicht wiederholt werden. Daher schlagen auch alle nachfolgenden Jobs in der Kette fehl.

Dieselbe Logik gilt, wenn ein OneTimeWorkRequest abgebrochen wird. Alle abhängigen Arbeitsanfragen sind ebenfalls mit CANCELLED gekennzeichnet und ihre Arbeit wird nicht ausgeführt.

Diagramm, das eine Kette von Jobs zeigt. Ein Job wurde abgebrochen. Daher werden alle nachfolgenden Jobs in der Kette ebenfalls abgebrochen.

Wenn Sie weitere Arbeitsanfragen an eine Kette anhängen, die fehlgeschlagene oder abgebrochene Arbeitsanfragen enthält, wird die neu angehängte Arbeitsanfrage ebenfalls als FAILED bzw. CANCELLED gekennzeichnet. Wenn Sie die Arbeit einer vorhandenen Kette erweitern möchten, finden Sie weitere Informationen unter APPEND_OR_REPLACE in existingWorkPolicy.

Beim Erstellen von Ketten von Arbeitsanfragen sollten für abhängige Arbeitsanfragen Richtlinien für Wiederholungen definiert werden, um sicherzustellen, dass die Arbeit immer rechtzeitig abgeschlossen wird. Fehlgeschlagene Arbeitsanfragen können zu unvollständigen Ketten und/oder zu einem unerwarteten Status führen.

Weitere Informationen finden Sie unter Arbeit abbrechen und beenden.