WorkManager umożliwia tworzenie i umieszczanie w kolejce łańcucha zadań, który określa wiele zależnych zadań i definiuje kolejność ich wykonywania. Ta funkcja jest szczególnie przydatna, gdy musisz wykonać kilka zadań w określonej kolejności.
Aby utworzyć łańcuch działań, możesz użyć funkcji
WorkManager.beginWith(OneTimeWorkRequest)
lub
WorkManager.beginWith(List<OneTimeWorkRequest>)
, które zwracają instancję
WorkContinuation
.
Za pomocą znaku WorkContinuation
można dodawać zależne instancje OneTimeWorkRequest
, używając then(OneTimeWorkRequest)
lub then(List<OneTimeWorkRequest>)
.
Każde wywołanie funkcji WorkContinuation.then(...)
zwraca nową instancję funkcji WorkContinuation
. Jeśli dodasz List
instancji OneTimeWorkRequest
, te żądania mogą być wykonywane równolegle.
Na koniec możesz użyć metody
WorkContinuation.enqueue()
do enqueue()
łańcucha WorkContinuation
.
Przeanalizujmy przykład. W tym przykładzie skonfigurowano 3 różne zadania Worker, które mają być wykonywane (potencjalnie równolegle). Wyniki tych instancji roboczych są następnie łączone i przekazywane do zadania instancji roboczej buforowania. Na koniec dane wyjściowe tego zadania są przekazywane do procesu przesyłania, który 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();
Łączenie danych wejściowych
Gdy połączysz ze sobą instancje OneTimeWorkRequest
, dane wyjściowe żądań pracy nadrzędnej
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
.
Aby zarządzać danymi wejściowymi z wielu nadrzędnych żądań pracy, WorkManager używa InputMerger
.
WorkManager udostępnia 2 rodzaje InputMerger
:
OverwritingInputMerger
próbuje dodać wszystkie klucze ze wszystkich wejść do wyjścia. W przypadku konfliktu zastępuje wcześniej ustawione klucze.ArrayCreatingInputMerger
próbuje scalić dane wejściowe, tworząc w razie potrzeby tablice.
Jeśli masz bardziej konkretny przypadek użycia, możesz napisać własną klasę, tworząc podklasę klasy InputMerger
.
OverwritingInputMerger
OverwritingInputMerger
to domyślna metoda łączenia. Jeśli podczas scalania wystąpią konflikty kluczy, najnowsza wartość klucza zastąpi wszystkie poprzednie wersje w wynikowych danych wyjściowych.
Jeśli na przykład dane wejściowe każdego zakładu mają klucz pasujący do odpowiedniej nazwy zmiennej ("plantName1"
, "plantName2"
i "plantName3"
), dane przekazywane do instancji roboczej cache
będą zawierać 3 pary klucz-wartość.
Jeśli wystąpi konflikt, „wygrywa” ostatni pracownik, który ukończył zadanie, a jego wartość jest przekazywana do cache
.
Żądania pracy są wykonywane równolegle, więc nie masz gwarancji kolejności ich wykonywania. W powyższym przykładzie zmienna plantName1
może mieć wartość "tulip"
lub "elm"
w zależności od tego, która wartość zostanie zapisana jako ostatnia. Jeśli istnieje ryzyko konfliktu kluczy i musisz zachować wszystkie dane wyjściowe w procesie łączenia, lepszym rozwiązaniem może być ArrayCreatingInputMerger
.
ArrayCreatingInputMerger
W powyższym przykładzie, ponieważ chcemy zachować dane wyjściowe wszystkich instancji roboczych plant
name, powinniśmy użyć znaku 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
przypisuje do każdego klucza tablicę. Jeśli każdy z kluczy jest niepowtarzalny, wynikiem będzie seria tablic jednoelementowych.
Jeśli wystąpią kolizje kluczy, odpowiednie wartości zostaną zgrupowane w tablicy.
Łączenie i stany pracy
Łańcuchy OneTimeWorkRequest
są wykonywane sekwencyjnie, o ile ich działanie zakończy się pomyślnie (czyli zwrócą wartość Result.success()
). Żądania pracy mogą zakończyć się niepowodzeniem lub zostać anulowane podczas wykonywania, co ma wpływ na zależne żądania pracy.
Gdy w łańcuchu żądań pracy zostanie umieszczone pierwsze żądanie OneTimeWorkRequest
, wszystkie kolejne żądania pracy są blokowane do czasu zakończenia pracy tego pierwszego żądania.
Po dodaniu do kolejki i spełnieniu wszystkich ograniczeń dotyczących pracy rozpoczyna się wykonywanie pierwszego żądania pracy. Jeśli praca zostanie wykonana w OneTimeWorkRequest
lub List<OneTimeWorkRequest>
(czyli zwróci Result.success()
), zostanie umieszczony w kolejce następny zestaw zależnych żądań pracy.
Jeśli każde żądanie pracy zostanie zrealizowane, ten sam wzorzec będzie propagowany przez pozostałą część łańcucha żądań pracy, dopóki wszystkie zadania w łańcuchu nie zostaną wykonane. Chociaż jest to najprostszy i często preferowany przypadek, równie ważne jest obsługiwanie stanów błędów.
Jeśli podczas przetwarzania Twojego żądania przez pracownika wystąpi błąd, możesz ponowić to żądanie zgodnie z określonymi przez siebie zasadami wycofywania. Ponawianie żądania, które jest częścią łańcucha, oznacza, że tylko to żądanie zostanie ponowione z danymi wejściowymi, które zostały mu przekazane. Nie wpłynie to na żadne zadania wykonywane równolegle.
Więcej informacji o definiowaniu niestandardowych strategii ponawiania znajdziesz w zasadach ponawiania i wycofywania.
Jeśli zasady ponawiania są niezdefiniowane lub wyczerpane albo osiągniesz stan, w którym OneTimeWorkRequest
zwraca Result.failure()
, to żądanie pracy i wszystkie zależne żądania pracy są oznaczane jako FAILED.
.
Ta sama logika obowiązuje w przypadku anulowania OneTimeWorkRequest
. Wszystkie zależne prośby o wykonanie pracy są również oznaczone symbolem CANCELLED
i nie będą realizowane.
Pamiętaj, że jeśli dodasz kolejne prośby o wykonanie pracy do łańcucha, w którym wystąpił błąd lub w którym anulowano prośby o wykonanie pracy, nowo dodane prośby o wykonanie pracy również zostaną oznaczone odpowiednio symbolem FAILED
lub CANCELLED
. Jeśli chcesz rozszerzyć zakres prac w ramach istniejącego łańcucha, zapoznaj się z sekcją APPEND_OR_REPLACE
w ExistingWorkPolicy.
Podczas tworzenia łańcuchów żądań pracy zależne żądania pracy powinny definiować zasady ponawiania, aby zapewnić terminowe wykonanie pracy. Nieudane żądania pracy mogą powodować niekompletne łańcuchy lub nieoczekiwany stan.
Więcej informacji znajdziesz w sekcji Anulowanie i zatrzymywanie pracy.