Aufgaben verketten

Mit WorkManager können Sie eine Arbeitskette erstellen und in eine Warteschlange einreihen, in der mehrere abhängige Aufgaben angegeben sind und die definiert, in welcher Reihenfolge sie ausgeführt werden sollen. 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. Diese geben jeweils eine Instanz von WorkContinuation zurück.

Mit einem 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 eine List von OneTimeWorkRequest Instanzen hinzufügen, können diese Anfragen möglicherweise parallel ausgeführt werden.

Schließlich können Sie mit der Methode WorkContinuation.enqueue() eine enqueue()-Kette von WorkContinuations 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 Worker-Job im Cache übergeben. Schließlich wird die Ausgabe dieses Jobs an einen Upload-Worker übergeben, der die Ergebnisse auf einen Remoteserver 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();

Eingabe-Fusionen

Wenn Sie OneTimeWorkRequest-Instanzen verketten, wird die Ausgabe von übergeordneten 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.

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

WorkManager bietet zwei verschiedene Arten von InputMerger:

  • OverwritingInputMerger versucht, der Ausgabe alle Schlüssel aus allen Eingaben 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 eigene Klassen erstellen, indem Sie von InputMerger abgeleitete Klassen erstellen.

Eingabezusammenführung überschreiben

OverwritingInputMerger ist die standardmäßige Zusammenführungsmethode. Wenn es in der Zusammenführung Schlüsselkonflikte gibt, werden alle vorherigen Versionen in den resultierenden Ausgabedaten durch den neuesten Wert für einen Schlüssel überschrieben.

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

Diagramm mit drei Jobs, die verschiedene 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.

Wenn ein Konflikt auftritt, gewinnt der letzte Worker, der den Vorgang abgeschlossen hat, und sein Wert wird 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. Der nächste Job erhält dann zwei Schlüssel/Wert-Paare, wobei eine der in Konflikt stehenden Ausgaben verworfen wird.

Da Ihre Arbeitsanfragen parallel ausgeführt werden, können Sie die Reihenfolge, in der sie ausgeführt werden, nicht garantieren. 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.

ArrayErstellenEingabezusammenführung

Für das obige Beispiel sollten wir ArrayCreatingInputMerger verwenden, da wir die Ausgaben aller Anlagennamen Worker beibehalten möchten.

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

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

Wenn Schlüsselkollisionen auftreten, werden die 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. Im nächsten Job werden zwei Arrays übergeben, eines für jeden Schlüssel. Eines dieser Arrays hat zwei Mitglieder, da es zwei Ausgaben mit diesem Schlüssel gab.

Verkettung und Arbeitsstatus

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

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

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

Sobald Sie in die Warteschlange gestellt wurden 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 mit einer Kette von Jobs. Der erste Job war erfolgreich und seine beiden unmittelbaren Nachfolger werden in die Warteschlange gestellt. Die verbleibenden Jobs werden blockiert, da sie ihre vorherige Ausführung beenden.

Solange jede Arbeitsanfrage erfolgreich abgeschlossen wird, wird dieses Muster durch die restliche Arbeitskette weitergegeben, bis alle Arbeit in der Kette abgeschlossen ist. Dies ist zwar der einfachste und oft bevorzugte Fall, aber die Behandlung von Fehlerstatus ist genauso wichtig.

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

Diagramm mit einer Kette von Jobs. Einer der Jobs ist fehlgeschlagen, es wurde jedoch eine Backoff-Richtlinie definiert. Dieser Job wird noch einmal ausgeführt, nachdem die entsprechende Zeit verstrichen ist. Die Jobs, die in der Kette folgen, werden blockiert, bis er erfolgreich ausgeführt wird.

Weitere Informationen zum Definieren benutzerdefinierter 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. gekennzeichnet.

Diagramm mit einer Kette von Jobs. Ein Job ist fehlgeschlagen und kann nicht wiederholt werden. Infolgedessen schlagen auch alle nachfolgenden Jobs in der Kette fehl.

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

Diagramm mit einer Kette von Jobs. Ein Job wurde abgebrochen. Infolgedessen werden alle Jobs, die in der Kette folgen, ebenfalls abgebrochen.

Wenn Sie weitere Arbeitsanfragen an eine Kette anhängen, die fehlgeschlagen ist oder abgebrochene Arbeitsanfragen hat, 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 VorhandeneWorkPolicy.

Beim Erstellen von Ketten von Arbeitsanfragen sollten abhängige Arbeitsanfragen Richtlinien für Wiederholungen definieren, um sicherzustellen, dass die Arbeit immer zügig 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.