WorkManager umożliwia tworzenie i umieszczanie w kole zadań w łańcuchu, które określają wiele zależnych od siebie zadań i określają ich kolejność. Ta funkcja jest szczególnie przydatna, gdy chcesz wykonać kilka zadań w określonej kolejności.
Aby utworzyć łańcuch zadań, możesz użyć funkcji WorkManager.beginWith(OneTimeWorkRequest)
lub WorkManager.beginWith(List<OneTimeWorkRequest>)
, które zwracają instancjęWorkContinuation
.
Następnie za pomocą WorkContinuation
można dodawać zależne wystąpienia OneTimeWorkRequest
za pomocą then(OneTimeWorkRequest)
lub then(List<OneTimeWorkRequest>)
.
Każde wywołanie funkcji WorkContinuation.then(...)
zwraca nowe wystąpienie funkcji WorkContinuation
. Jeśli dodasz List
instancji OneTimeWorkRequest
, te żądania mogą być wykonywane równolegle.
Na koniec możesz użyć metody WorkContinuation.enqueue()
, aby enqueue()
łańcuch WorkContinuation
.
Przeanalizujmy to na przykładzie. W tym przykładzie 3 różne zadania Worker są skonfigurowane do wykonania (opcjonalnie w ramach działania równoległego). Wyniki tych instancji roboczych są następnie łączone i przekazywane do instancji roboczej z funkcjami buforowania. W końcu dane wyjściowe tego zadania są przekazywane do roboczego przesyłania, które przesyła wyniki na zdalny serwer.
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();
Złączenia danych wejściowych
Gdy połączysz instancje OneTimeWorkRequest
, dane wyjściowe żądań rodzicielskich zostaną przekazane jako dane wejściowe do podrzędnych. W tym przykładzie dane wyjściowe plantName1
, plantName2
i plantName3
są przekazywane jako dane wejściowe do żądania cache
.
Aby zarządzać danymi wejściowymi z wielu nadrzędnych zadań, WorkManager używa interfejsu InputMerger
.
WorkManager udostępnia 2 rodzaje InputMerger
:
OverwritingInputMerger
próbuje dodać wszystkie klucze ze wszystkich wejść do danych wyjściowych. W przypadku konfliktów zastąpi on wcześniej ustawione klucze.ArrayCreatingInputMerger
próbuje scalić dane wejściowe, tworząc w razie potrzeby tablice.
Jeśli masz bardziej szczegółowy przypadek użycia, możesz napisać własny, tworząc podklasę InputMerger
.
OverwritingInputMerger
OverwritingInputMerger
to domyślna metoda scalania. Jeśli podczas scalania wystąpią konflikty kluczy, najnowsza wartość klucza zastąpi wszystkie poprzednie wersje w wynikających danych wyjściowych.
Jeśli np. każdy z wejść plant ma klucz pasujący do nazwy odpowiedniej zmiennej ("plantName1"
, "plantName2"
i "plantName3"
), dane przekazywane do instancji roboczej cache
będą zawierać 3 pary klucz-wartość.
W przypadku konfliktu „wygrywa” ostatni pracownik, który ukończył zadanie, a jego wartość jest przekazywana do cache
.
Twoje żądania robocze są wykonywane równolegle, więc nie masz gwarancji, w jakiej kolejności będą wykonywane. W powyższym przykładzie zmienna plantName1
może zawierać 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 podczas scalania, ArrayCreatingInputMerger
może być lepszą opcją.
ArrayCreatingInputMerger
W przypadku powyższego przykładu, ponieważ chcemy zachować dane wyjściowe ze wszystkich pracowników fabryki o nazwie Workers, powinniśmy użyć 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
łączy każdy klucz z tablicą. Jeśli każdy z kluczy jest niepowtarzalny, wynik to seria tablic jednoelementowych.
Jeśli wystąpią kolizje kluczy, wszystkie odpowiadające im wartości zostaną pogrupowane w tablicy.
Łańcuch i stany pracy
Łańcuchy OneTimeWorkRequest
są wykonywane sekwencyjnie, dopóki ich wykonanie się powiedzie (czyli zwrócą wartość Result.success()
). Żądania mogą się nie udać lub zostać anulowane podczas wykonywania, co ma wpływ na zależne żądania pracy.
Gdy pierwsze OneTimeWorkRequest
zostanie umieszczone w kolejce w łańcuchu żądań pracy, wszystkie kolejne żądania pracy są blokowane do czasu zakończenia pracy związanej z pierwszym żądaniem.
Gdy zadanie zostanie umieszczone w kolejce i spełnione zostaną wszystkie ograniczenia, rozpocznie się wykonywanie pierwszego żądania pracy. Jeśli zadanie zostanie wykonane w korzeniach OneTimeWorkRequest
lub List<OneTimeWorkRequest>
(czyli zwróci wartość Result.success()
), następny zestaw zależnych żądań pracy zostanie umieszczony w kole.
Dopóki każde żądanie pracy zostanie zrealizowane, ten sam wzór będzie się rozprzestrzeniał w dalszej części łańcucha żądań pracy, aż do momentu, gdy wszystkie zadania zostaną ukończone. Chociaż jest to najprostszy i najczęściej preferowany przypadek, stany błędów są równie ważne.
Jeśli podczas przetwarzania Twojego żądania pracy wystąpi błąd, możesz ponownie przesłać to żądanie zgodnie z zdefiniowanymi przez Ciebie zasadami wycofywania. Ponowne próby wykonania żądania, które jest częścią łańcucha, oznaczają, że zostanie ono powtórnie wykonane z podawanymi mu danymi wejściowymi. Nie wpłynie to na żadne zadania wykonywane równolegle.
Więcej informacji o definiowaniu niestandardowych strategii ponownych prób znajdziesz w artykule Zasady ponownych prób i zmniejszonej intensywności.
Jeśli zasada ponownego próbowania jest niezdefiniowana lub wyczerpana albo jeśli w jakimś stanie OneTimeWorkRequest
zwraca wartość Result.failure()
, to żądanie pracy i wszystkie zależne żądania pracy są oznaczane jako FAILED.
.
Ta sama zasada obowiązuje, gdy anulujesz OneTimeWorkRequest
. Wszystkie zależne zadania zostaną również oznaczone jako CANCELLED
i nie zostaną wykonane.
Jeśli dodasz więcej próśb o wykonanie pracy do łańcucha, który nie powiódł się lub został anulowany, nowo dodana prośba o wykonanie pracy również zostanie oznaczona odpowiednio jako FAILED
lub CANCELLED
. Jeśli chcesz rozszerzyć zakres pracy w ramach istniejącego łańcucha, zapoznaj się z sekcją APPEND_OR_REPLACE
w ExistingWorkPolicy.
Podczas tworzenia łańcuchów żądań pracy żądania zależne powinny definiować zasady ponownych prób, aby zapewnić terminowe wykonywanie pracy. Nieudane żądania pracy mogą spowodować niekompletne łańcuchy lub nieoczekiwany stan.
Więcej informacji znajdziesz w artykule Anulowanie i przerywanie pracy.