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 zadań, możesz użyć funkcji
WorkManager.beginWith(OneTimeWorkRequest)
lub
WorkManager.beginWith(List<OneTimeWorkRequest>)
, które zwracają instancję
WorkContinuation.
Następnie można użyć WorkContinuation, aby dodać zależne instancje OneTimeWorkRequest za pomocą 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 powyższym przykładzie dane wyjściowe z 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:
OverwritingInputMergerpróbuje dodać wszystkie klucze ze wszystkich wejść do wyjścia. W przypadku konfliktu zastępuje wcześniej ustawione klucze.ArrayCreatingInputMergerpróbuje scalić dane wejściowe, tworząc w razie potrzeby tablice.
Jeśli masz bardziej konkretne zastosowanie, 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 funkcji mają klucz pasujący do odpowiednich nazw zmiennych ("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 wykonał zadanie, a jego wartość jest przekazywana do cache.
Ponieważ żądania pracy są wykonywane równolegle, nie masz gwarancji kolejności ich wykonywania. 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 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ę powodzeniem (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 katalogu głównymOneTimeWorkRequest 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 resztę ł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 dostarczonymi do niego danymi wejściowymi. 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 funkcja OneTimeWorkRequest zwraca wartość 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 prośby o wykonanie zadań zależnych są również oznaczone symbolem CANCELLED, a prace nie będą wykonywane.
Pamiętaj, że jeśli dołączysz więcej próśb o wykonanie pracy do łańcucha, w którym wystąpił błąd lub w którym anulowano prośby o wykonanie pracy, nowo dołączona prośba o wykonanie pracy również zostanie oznaczona odpowiednio symbolem FAILED lub CANCELLED. Jeśli chcesz rozszerzyć zakres prac 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.