Aufgaben verketten

Mit WorkManager können Sie eine Arbeitskette erstellen und in die Warteschlange stellen, die mehrere abhängige Aufgaben angibt und festlegt, 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öchten.

Zum Erstellen einer Arbeitskette können Sie WorkManager.beginWith(OneTimeWorkRequest) oder WorkManager.beginWith(List<OneTimeWorkRequest>) verwenden. Beide geben 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.

Jede Aufrufung von WorkContinuation.then(...) gibt eine neue Instanz von WorkContinuation zurück. Wenn Sie eine List von 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 Ihre WorkContinuation-Kette zu enqueue().

Sehen wir uns ein Beispiel an. In diesem Beispiel sind drei verschiedene Worker-Jobs für die Ausführung konfiguriert (potenziell parallel). Die Ergebnisse dieser Worker werden dann zusammengeführt und an einen Worker-Job für das Caching übergeben. Die Ausgabe dieses Jobs wird schließlich 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();

Eingabezusammenführungen

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

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, 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 eine eigene Klasse erstellen, indem Sie eine Unterklasse von InputMerger erstellen.

OverwritingInputMerger

OverwritingInputMerger ist die Standardmethode für die Zusammenführung. Wenn es bei der Zusammenführung zu Schlüsselkonflikten kommt, werden alle vorherigen Versionen in den resultierenden Ausgabedaten durch den neuesten Wert für einen Schlüssel überschrieben.

Wenn die Eingaben der Anlage beispielsweise jeweils einen Schlüssel haben, der mit den jeweiligen Variablennamen ("plantName1", "plantName2" und "plantName3") übereinstimmt, enthalten die an den cache-Worker ü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 unterschiedliche Schlüssel haben, erhält der nächste Job drei Schlüssel/Wert-Paare.

Bei einem Konflikt „gewinnt“ der letzte Worker, der die Aufgabe abgeschlossen hat, und sein Wert wird an cache übergeben.

Diagramm mit drei Jobs, die die Ausgabe an den nächsten Job in der Kette weitergeben. In diesem Fall erzeugen zwei dieser Jobs Ausgaben mit demselben Schlüssel. Daher erhält der nächste Job zwei Schlüssel/Wert-Paare, wobei eine der konfliktierenden Ausgaben entfernt wird.

Da Ihre Arbeitsanfragen parallel ausgeführt werden, können Sie nicht sicher sein, in welcher Reihenfolge sie ausgeführt werden. Im obigen Beispiel kann plantName1 den Wert "tulip" oder "elm" haben, je nachdem, welcher Wert zuletzt geschrieben wird. Wenn die Wahrscheinlichkeit eines Schlüsselkonflikts hoch ist und Sie alle Ausgabedaten bei einer Zusammenführung beibehalten müssen, ist ArrayCreatingInputMerger möglicherweise die bessere Option.

ArrayCreatingInputMerger

Da wir in unserem Beispiel die Ausgabe aller Worker mit dem Attribut „Name der Anlage“ beibehalten möchten, sollten wir eine 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();

Bei ArrayCreatingInputMerger wird jeder Schlüssel mit einem Array verknüpft. Wenn jeder Schlüssel eindeutig ist, ist das Ergebnis eine Reihe von Arrays mit nur 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 Ausgabeschlüssel. Jedes Array hat ein einzelnes Mitglied.

Bei Schlüsselkollisionen werden die entsprechenden Werte in einem Array zusammengefasst.

Diagramm mit drei Jobs, die die Ausgabe an den nächsten Job in der Kette weitergeben. 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.

Verknüpfung 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 fehlschlagen oder während der Ausführung abgebrochen werden, was Auswirkungen auf abhängige Arbeitsanfragen hat.

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

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

Sobald die Anfrage in die Warteschlange aufgenommen wurde und alle Arbeitseinschränkungen erfüllt sind, wird die erste Arbeitsanfrage ausgeführt. Wenn die Arbeit im Stammverzeichnis OneTimeWorkRequest oder List<OneTimeWorkRequest> erfolgreich abgeschlossen wurde (d. h. Result.success() zurückgegeben wurde), werden die nächsten abhängigen Arbeitsanfragen in die Warteschlange gestellt.

Diagramm mit einer Jobkette Der erste Job war erfolgreich und seine beiden unmittelbaren Nachfolger wurden in die Warteschlange gestellt. Die verbleibenden Jobs werden blockiert, bis die vorherigen Jobs abgeschlossen sind.

Solange jede Arbeitsanfrage erfolgreich abgeschlossen wird, wird dieses Muster auf die restliche Arbeitsanfragekette angewendet, bis alle Aufgaben in der Kette abgeschlossen sind. Das ist zwar der einfachste und oft bevorzugte Fall, aber auch Fehlerstatus müssen genauso behandelt werden.

Wenn bei der Verarbeitung Ihrer Arbeitsanfrage durch einen Worker ein Fehler auftritt, können Sie diese Anfrage gemäß einer von Ihnen definierten Backoff-Richtlinie noch einmal versuchen. Wenn Sie eine Anfrage wiederholen, die Teil einer Kette ist, wird nur diese Anfrage mit den angegebenen Eingabedaten wiederholt. Parallel ausgeführte Aufgaben sind davon nicht betroffen.

Diagramm mit einer Jobkette Einer der Jobs ist fehlgeschlagen, aber es war eine Backoff-Richtlinie definiert. Dieser Job wird nach Ablauf der entsprechenden Zeit noch einmal ausgeführt. Die Jobs in der Kette, die nach diesem Job kommen, werden blockiert, bis er erfolgreich ausgeführt wurde.

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

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

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

Das Gleiche gilt, wenn eine OneTimeWorkRequest storniert wird. Alle abhängigen Arbeitsanfragen werden ebenfalls mit CANCELLED gekennzeichnet und die zugehörigen Arbeitsschritte werden nicht ausgeführt.

Diagramm mit einer Jobkette Ein Job wurde abgebrochen. Daher werden auch alle nachfolgenden Jobs in der Kette abgebrochen.

Wenn Sie einer Kette, die fehlgeschlagen ist oder bei der Arbeitsanfragen abgebrochen wurden, weitere Arbeitsanfragen anhängen, wird auch die neu angehängte Arbeitsanfrage mit FAILED bzw. CANCELLED gekennzeichnet. Wenn Sie die Arbeit einer vorhandenen Kette verlängern möchten, lesen Sie den Abschnitt APPEND_OR_REPLACE in ExistingWorkPolicy.

Wenn Sie Arbeitsanfrageketten erstellen, sollten Sie für abhängige Arbeitsanfragen Wiederholungsrichtlinien definieren, damit die Arbeit immer zeitnah abgeschlossen wird. Fehlgeschlagene Arbeitsanfragen können zu unvollständigen Ketten und/oder unerwarteten Status führen.

Weitere Informationen finden Sie unter Aufgaben abbrechen und anhalten.