WorkManager pozwala utworzyć i umieścić w kolejce łańcuch zadań, który określa wiele zależnych zadań i określa kolejność ich wykonywania. Ta funkcja jest szczególnie przydatna, gdy musisz uruchomić kilka zadań w określonej kolejności.
Aby utworzyć łańcuch zadań, możesz użyć WorkManager.beginWith(OneTimeWorkRequest)
lub WorkManager.beginWith(List<OneTimeWorkRequest>)
, które zwracają wystąpienie WorkContinuation
.
Następnie możesz użyć WorkContinuation
, aby dodać zależne instancje OneTimeWorkRequest
za pomocą then(OneTimeWorkRequest)
lub then(List<OneTimeWorkRequest>)
.
Każde wywołanie metody WorkContinuation.then(...)
zwraca nowe wystąpienie WorkContinuation
. Jeśli dodasz List
z OneTimeWorkRequest
instancji, te żądania mogą potencjalnie być uruchamiane równolegle.
Na koniec możesz użyć metody WorkContinuation.enqueue()
, aby enqueue()
łańcucha WorkContinuation
.
Przeanalizujmy przykład. W tym przykładzie skonfigurowane są 3 różne zadania instancji roboczych (potencjalnie równolegle). Wyniki tych instancji roboczych są łączone i przekazywane do zadania buforowania. Na koniec dane wyjściowe zadania są przekazywane do instancji roboczej przesyłającej, która przesyła wyniki na serwer zdalny.
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();
Scalanie danych wejściowych
Gdy łączysz łańcuch instancji OneTimeWorkRequest
, dane wyjściowe nadrzędnych żądań pracy są przekazywane jako dane wejściowe do elementów podrzędnych. W przykładzie powyżej dane wyjściowe funkcji plantName1
, plantName2
i plantName3
zostaną przekazane jako dane wejściowe do żądania cache
.
Do zarządzania danymi wejściowymi z wielu nadrzędnych żądań roboczych WorkManager używa metody InputMerger
.
WorkManager udostępnia 2 różne typy InputMerger
:
OverwritingInputMerger
próbuje dodać do danych wyjściowych wszystkie klucze ze wszystkich danych wejściowych. W razie konfliktów zastępuje wcześniej ustawione klucze.ArrayCreatingInputMerger
próbuje scalić dane wejściowe, aby w razie potrzeby utworzyć tablice.
Jeśli masz bardziej konkretny przypadek użycia, możesz utworzyć własny, podklasyfikując InputMerger
.
Zastąpienie scalania danych wejściowych
OverwritingInputMerger
jest domyślną metodą scalania. Jeśli w przypadku scalania wystąpią konflikty kluczy, najnowsza wartość klucza zastąpi wszelkie wcześniejsze wersje w wynikowych danych.
Jeśli np. dane wejściowe rośliny mają klucz pasujący do swoich nazw zmiennych ("plantName1"
, "plantName2"
i "plantName3"
), dane przekazywane do instancji roboczej cache
będą miały 3 pary klucz-wartość.
W przypadku konfliktu ostatnia instancja robocza, która wykonała zadanie „wygrane”, jest przekazywana do funkcji cache
.
Żądania pracy są realizowane równolegle, więc nie możesz mieć gwarancji kolejności, w jakiej będą realizowane. W przykładzie powyżej plantName1
może zawierać wartość "tulip"
lub "elm"
, w zależności od tego, która wartość jest zapisywana jako ostatnia. Jeśli istnieje ryzyko konfliktu kluczy i chcesz zachować wszystkie dane wyjściowe w ramach scalania, lepszym rozwiązaniem może być użycie ArrayCreatingInputMerger
.
Metoda scalania tabel
W podanym wyżej przykładzie chcemy zachować dane wyjściowe wszystkich instancji roboczych o nazwach roślin, dlatego użyjemy właściwości 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
paruje każdy klucz z tablicą. Jeśli każdy z kluczy jest unikalny, wynik jest szeregiem jednoelementowych tablic.
Jeśli wystąpią konflikty kluczy, wszystkie odpowiadające im wartości zostaną zgrupowane w tablicy.
Stany związane z łańcuchami i pracą
Łańcuchy obiektów OneTimeWorkRequest
są wykonywane po kolei, o ile ich praca zakończy się powodzeniem (czyli zwraca wartość Result.success()
). Podczas wykonywania żądania pracy mogą się zakończyć niepowodzeniem lub anulować, co ma wpływ na zależne żądania pracy.
Gdy pierwsze OneTimeWorkRequest
zostanie umieszczone w kolejce w łańcuchu żądań pracy, wszystkie kolejne są blokowane do momentu zakończenia tego pierwszego.
Po umieszczeniu w kolejce i spełnieniu wszystkich ograniczeń zadania rozpoczyna się pierwsze żądanie. Jeśli zadanie zostanie wykonane w katalogu głównym OneTimeWorkRequest
lub List<OneTimeWorkRequest>
(czyli zwróci wartość Result.success()
), w kolejce pojawi się następny zestaw zależnych żądań roboczych.
Jeśli każde żądanie pracy zostanie zrealizowane, ten sam wzorzec będzie promował resztę łańcucha żądań, aż wszystkie zadania zostaną wykonane w łańcuchu. Chociaż jest to najprostszy i często preferowany przypadek, stany błędów są równie ważne, jak ich obsługa.
Jeśli podczas przetwarzania Twojego żądania służbowego przez instancję roboczą wystąpi błąd, możesz spróbować to żądanie jeszcze raz zgodnie ze zdefiniowaną przez Ciebie zasadą ponawiania. Ponowienie żądania, które jest częścią łańcucha, oznacza, że tylko to żądanie zostanie wykonane z dostarczonymi do niego danymi wejściowymi. Nie będzie to miało wpływu na pracę wykonywaną równolegle.
Więcej informacji o definiowaniu niestandardowych strategii ponawiania prób znajdziesz w artykule Zasady ponawiania i ponawiania.
Jeśli ta zasada ponawiania jest niezdefiniowana lub wyczerpana albo jeśli w inny sposób osiągniesz stan, w którym OneTimeWorkRequest
zwraca wartość Result.failure()
, to żądanie i wszystkie zależne żądania są oznaczone jako FAILED.
Ta sama logika obowiązuje w przypadku anulowania OneTimeWorkRequest
. Żądania pracy zależnej również są oznaczone jako CANCELLED
, a ich praca nie jest wykonywana.
Pamiętaj, że jeśli chcesz dołączyć więcej żądań pracy do łańcucha, którego przetwarzanie zakończyło się niepowodzeniem lub które je anulowało, nowo dołączone zlecenie również zostanie oznaczone odpowiednio FAILED
lub CANCELLED
. Jeśli chcesz przedłużyć działanie istniejącej sieci, zapoznaj się z opisem APPEND_OR_REPLACE
w Istniejącej zasadzie.
Podczas tworzenia łańcuchów żądań pracy zależne żądania powinny określać zasady ponawiania próby, aby zadania były zawsze wykonywane w odpowiednim czasie. Nieudane prośby o pracę mogą skutkować niepełnymi łańcuchami lub nieoczekiwanym stanem.
Więcej informacji znajdziesz w artykule Anulowanie i zatrzymywanie pracy.