WorkManager pozwala utworzyć i umieścić w kolejce łańcuch pracy, który określa wiele zależnych zadań i określa kolejność ich wykonywania. Ta funkcja jest szczególnie przydatna, gdy musisz uruchomić kilka zadań w określonej kolejności.
Aby utworzyć łańcuch pracy, możesz użyć funkcji WorkManager.beginWith(OneTimeWorkRequest)
lub WorkManager.beginWith(List<OneTimeWorkRequest>)
, które zwracają instancję WorkContinuation
.
Za pomocą WorkContinuation
można następnie dodać zależne instancje OneTimeWorkRequest
za pomocą then(OneTimeWorkRequest)
lub then(List<OneTimeWorkRequest>)
.
Każde wywołanie funkcji WorkContinuation.then(...)
zwraca nowe wystąpienie WorkContinuation
. Jeśli dodasz List
z OneTimeWorkRequest
instancji, te żądania mogą być uruchamiane równolegle.
Na koniec możesz użyć metody WorkContinuation.enqueue()
do enqueue()
swojego łańcucha WorkContinuation
.
Przeanalizujmy przykład. W tym przykładzie skonfigurowane do uruchamiania (potencjalnie równolegle) są skonfigurowane do uruchamiania 3 różne zadania instancji roboczej. Wyniki tych procesów roboczych są następnie łączone i przekazywane do zadania instancji roboczej buforowania. 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();
Fuzje danych wejściowych
W przypadku łączenia instancji OneTimeWorkRequest
dane wyjściowe nadrzędnych żądań zadań są przekazywane do elementów podrzędnych jako dane wejściowe. Zatem w tym przykładzie dane wyjściowe plantName1
, plantName2
i plantName3
byłyby przekazywane jako dane wejściowe do żądania cache
.
Do zarządzania danymi wejściowymi z wielu nadrzędnych żądań roboczych usługa WorkManager używa metody InputMerger
.
WorkManager udostępnia 2 różne typy znaczników InputMerger
:
OverwritingInputMerger
próbuje dodać do danych wyjściowych wszystkie klawisze ze wszystkich wejść. W przypadku konfliktów zastępuje wcześniej ustawione klucze.ArrayCreatingInputMerger
próbuje połączyć dane wejściowe, w razie potrzeby tworzy tablice.
Jeśli potrzebujesz bardziej szczegółowego przypadku użycia, możesz utworzyć własny, przypisując klasyfikację InputMerger
.
Nadpisanie danych wejściowych
Domyślną metodą scalania jest OverwritingInputMerger
. Jeśli w scalaniu wystąpią konflikty kluczy, najnowsza wartość klucza zastąpi wszystkie wcześniejsze wersje w wynikowych danych wyjściowych.
Jeśli na przykład każde z danych wejściowych „rośliny” ma klucz zgodny z odpowiednimi nazwami zmiennych ("plantName1"
, "plantName2"
i "plantName3"
), dane przekazywane do instancji roboczej cache
będą miały 3 pary klucz-wartość.
W przypadku konfliktu ostatni robot roboczy, który ukończył proces „wygrane”, a jego wartość jest przekazywana do funkcji cache
.
Żądania robocze są uruchamiane równolegle, więc nie masz gwarancji co do kolejności ich wykonywania. 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 występuje ryzyko konfliktu kluczy i chcesz zachować wszystkie dane wyjściowe w ramach scalania, lepszym rozwiązaniem będzie ArrayCreatingInputMerger
.
Scalanie_tablic
W powyższym przykładzie, ponieważ chcemy zachować dane wyjściowe wszystkich instancji roboczych nazwy fabryki, musimy użyć obiektu 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
paruje każdy klucz z tablicą. Jeśli każdy z kluczy jest unikalny, wynik to seria tablic jednoelementowych.
Jeśli wystąpią kolizje kluczy, wszystkie odpowiadające im wartości są zgrupowane w tablicy.
Łańcuch i stany pracy
Łańcuchy instancji OneTimeWorkRequest
są wykonywane sekwencyjnie, dopóki zadanie się powiedzie (tzn. zwróci wartość Result.success()
). Żądania zadania mogą podczas działania zakończyć się niepowodzeniem lub zostać anulowane, co ma wpływ na dalsze zależne żądania pracy.
Gdy pierwszy OneTimeWorkRequest
zostanie umieszczony w kolejce w łańcuchu żądań, wszystkie kolejne żądania robocze są blokowane do czasu zakończenia pracy pierwszego żądania.
Po umieszczeniu w kolejce i spełnieniu wszystkich ograniczeń roboczych zaczyna się działać pierwsze żądanie robocze. Jeśli zadanie zostało ukończone w katalogu głównym OneTimeWorkRequest
lub List<OneTimeWorkRequest>
(tzn. zwraca Result.success()
), kolejna grupa zależnych żądań roboczych zostanie dodana do kolejki.
Jeśli każde żądanie zadania zostanie zrealizowane, ten sam wzorzec będzie obowiązywać w pozostałej części łańcucha żądań aż do ukończenia całej pracy w łańcuchu. To najprostszy i najczęściej preferowany przypadek, jednak równie ważne są stany błędu.
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. Ponowienie próby żądania, które jest częścią łańcucha, oznacza, że zostanie ponowiona próba z użyciem dostarczonych danych wejściowych. Nie będzie to miało wpływu na współpracę prowadzoną równolegle.
Więcej informacji na temat definiowania niestandardowych strategii ponownych prób znajdziesz w zasadach ponawiania i wycofywania.
Jeśli ta zasada ponownych prób jest nieokreślona lub wyczerpana albo w inny sposób dojdziesz do stanu, w którym OneTimeWorkRequest
zwraca wartość Result.failure()
, to żądanie i wszystkie zależne żądania pracy są oznaczone jako FAILED.
Te same zasady obowiązują w przypadku anulowania polecenia OneTimeWorkRequest
. Wszystkie zależne żądania zadań są również oznaczane jako CANCELLED
, a ich zadania nie będą wykonywane.
Pamiętaj, że jeśli dodasz więcej żądań roboczych do łańcucha, który nie powiódł się lub które anulował żądania, nowo dołączone żądanie robocze również zostanie oznaczone odpowiednio 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 zatrzymywanie pracy.