WorkManager pozwala utworzyć i umieścić w kolejce łańcuch pracy, który określa wiele zależnych zadań oraz określa 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 nowy egzemplarz funkcji WorkContinuation
. Jeśli dodasz List
wystąpień OneTimeWorkRequest
, te żądania mogą być wykonywane równolegle.
Na koniec możesz użyć metody WorkContinuation.enqueue()
do enqueue()
swojego łańcucha WorkContinuation
.
Przeanalizujmy to na przykładzie. W tym przykładzie 3 różne zadania Worker są skonfigurowane do wykonania (opcjonalnie w drodze równoległej). Wyniki tych zadań są następnie łączone i przekazywane do zadania Workera obsługującego buforowanie. Dane wyjściowe tego zadania są przekazywane do instancji roboczej przesyłania, która 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 danych wejściowych do danych wyjściowych. W przypadku konfliktów zastępuje wcześniej ustawione klucze.ArrayCreatingInputMerger
próbuje scalić dane wejściowe, tworząc w razie potrzeby tablice.
Jeśli chcesz podać bardziej szczegółowy przypadek użycia, możesz utworzyć własny, przypisując klasyfikację 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 instancji roboczej cache
będą zawierać 3 pary klucz-wartość.
Jeśli wystąpi konflikt, jako ostatni robot roboczy ukończył „wygrane”, a jego wartość jest przekazywana do funkcji 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 plantName1
może zawierać wartość "tulip"
lub "elm"
zależnie od tego, jaka wartość została 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();
Funkcja 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ńcuchowanie i stany pracy
Łańcuchy OneTimeWorkRequest
są wykonywane sekwencyjnie, dopóki ich wykonanie się powiedzie (czyli zwrócą wartość Result.success()
). Żądania o wykonanie pracy mogą się nie udać lub zostać anulowane podczas wykonywania, co ma wpływ na zależne żądania o wykonanie 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 zadań 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 błąd wystąpi, gdy instancja robocza przetwarza Twoje żądanie robocze, możesz spróbować je wysłać ponownie zgodnie ze zdefiniowaną przez siebie zasadą ponowienia. Ponowne próby wykonania żądania, które jest częścią łańcucha, oznaczają, że zostanie ono powtórnie wykonane z podawanymi danymi wejściowymi. Nie będzie to miało wpływu na współpracę prowadzoną równolegle.
Więcej informacji o definiowaniu niestandardowych strategii ponownych prób znajdziesz w artykule Zasady ponownych prób i zmniejszenia częstotliwoś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.
.
Te same zasady obowiązują w przypadku anulowania polecenia OneTimeWorkRequest
. Wszystkie zależne prośby o wykonanie pracy są też oznaczone jako CANCELLED
i nie będą wykonywane.
Jeśli dodasz więcej próśb o przeniesienie do łańcucha, który nie został zakończony lub został anulowany, nowo dodana prośba zostanie oznaczona odpowiednio jako FAILED
lub CANCELLED
. Jeśli chcesz rozszerzyć działanie istniejącego łańcucha, zobacz APPEND_OR_REPLACE
w existingWorkPolicy.
Podczas tworzenia łańcuchów żądań pracy zależne żądania pracy powinny określać zasady ponownych prób, aby zawsze były wykonywane w odpowiednim czasie. Nieudane żądania robocze mogą skutkować niepełnymi łańcuchami lub nieoczekiwanym stanem.
Więcej informacji znajdziesz w artykule Anulowanie i przerywanie pracy.