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.
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:
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 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 dotyczące rośliny 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.
Ponieważ żądania pracy są wykonywane równolegle, 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 zadań
Ł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 uruchomione 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 zadania 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.