Po zdefiniowaniu
Worker
i
WorkRequest
,
Ostatnią czynnością jest umieszczenie zadań w kolejce. Najprostszy sposób dodawania zadań do kolejki
jest wywołanie metody enqueue()
w WorkManager i przekazywaniu WorkRequest
co chce zrobić.
Kotlin
val myWork: WorkRequest = // ... OneTime or PeriodicWork WorkManager.getInstance(requireContext()).enqueue(myWork)
Java
WorkRequest myWork = // ... OneTime or PeriodicWork WorkManager.getInstance(requireContext()).enqueue(myWork);
Zachowaj ostrożność podczas dodawania zadań do kolejki, aby uniknąć ich duplikowania. Aplikacja może na przykład próbować przesłać do usługi backendu co 24 godziny. Jeśli nie zachowasz ostrożności, to samo zadanie zostanie umieszczone w kolejce wiele razy, mimo że musi ono które można uruchomić tylko raz. Aby osiągnąć ten cel, możesz zaplanować wykonanie niepowtarzalnej pracy.
Wyjątkowa praca
Unikalna praca to potężna koncepcja, która gwarantuje, że dysponujesz tylko jednym wystąpienia pracy o określonej nazwie naraz. W przeciwieństwie do identyfikatorów, unikalne nazwy są zrozumiałe dla człowieka i określone przez dewelopera, a nie generowane automatycznie; przez WorkManagera. Nie podoba mi się tags, unikalny użytkownik są powiązane tylko z jedną instancją pracy.
Unikalną pracę można wykorzystać zarówno do zadań jednorazowych, jak i okresowych. Możesz utworzyć w zależności od tego, czy gdy planujesz zadanie cykliczne lub jednorazowe.
WorkManager.enqueueUniqueWork()
za pracę jednorazowąWorkManager.enqueueUniquePeriodicWork()
za pracę okresową
W obu przypadkach można użyć 3 argumentów:
- uniqueWorkName –
String
służy do jednoznacznej identyfikacji utworu. użytkownika. - existingWorkPolicy –
enum
, który informuje usługę WorkManager, co ma zrobić czy mamy już niedokończony łańcuch zadań o takiej unikalnej nazwie. Zobacz zasady rozwiązywania konfliktów. - work –
WorkRequest
do zaplanowania.
Korzystając z tej możliwości, możemy rozwiązać wspomniany wcześniej zduplikowany problem z planowaniem.
Kotlin
val sendLogsWorkRequest = PeriodicWorkRequestBuilderS<endLogsWorker(>24, TimeUnit.HOURS) .setConstraints(Constraints.Builder() .setRequiresCharging(true) .build() ) .build() WorkManager.getInstance(this).enqueueUniquePeriodicWork( "sendLogs", ExistingPeriodicWorkPolicy.KEEP, sendLogsWorkRequest )
Java
PeriodicWorkRequest sendLogsWorkRequest = new PeriodicWorkRequest.Builder(SendLogsWorker.class, 24, TimeUnit.HOURS) .setConstraints(new Constraints.Builder() .setRequiresCharging(true) .build() ) .build(); WorkManager.getInstance(this).enqueueUniquePeriodicWork( "sendLogs", ExistingPeriodicWorkPolicy.KEEP, sendLogsWorkRequest);
Jeśli kod zostanie uruchomiony, gdy zadanie sendLogs jest już w kolejce, zadanie zostanie zachowane i nie zostanie dodane żadne nowe zadanie.
Unikalne sekwencje pracy mogą być też przydatne, jeśli musisz stopniowo tworzyć długie łańcucha zadań. Na przykład aplikacja do edycji zdjęć może pozwalać użytkownikom na cofanie długi łańcuch działań. Każda z tych operacji cofania może zająć trochę czasu, ale muszą być wykonywane we właściwej kolejności. W takim przypadku aplikacja może utwórz polecenie „cofnij” i w razie potrzeby dołączyć do łańcucha każdą operację cofania. Zobacz Łączenie zadań .
Zasady rozwiązywania konfliktów
Podczas planowania unikalnej pracy musisz poinformować WorkManagera, jakie działanie wykonać, gdy konflikt. Można to zrobić, dodając wartość wyliczeniową podczas umieszczania zadania w kolejce.
W przypadku pracy jednorazowej podajesz
ExistingWorkPolicy
, czyli
obsługuje 4 opcje obsługi konfliktu.
- Istniejące:
REPLACE
z nową pracą. Ta opcja powoduje anulowanie istniejącego zadania. KEEP
istniejących zadań oraz zignoruj nową pracę.APPEND
nowe zadanie na koniec istniejącej pracy. Te zasady spowodują, że Twoje nowe utwory będą łańcuch uruchomionej po zakończeniu pracy istniejącej.
Istniejący utwór staje się wymaganiem wstępnym dla nowego utworu. Jeśli dotychczasowy utwór
zmieni się na CANCELLED
lub FAILED
, nowa praca będzie również CANCELLED
lub FAILED
.
Jeśli chcesz, aby nowa praca była uruchamiana niezależnie od stanu istniejącej,
użyj interfejsu APPEND_OR_REPLACE
.
APPEND_OR_REPLACE
działa podobnie doAPPEND
, z tym wyjątkiem, że nie jest zależne od warunek wstępny. Jeśli istniejące dzieło toCANCELLED
lubFAILED
, nowe zadanie nadal trwa.
W przypadku pracy z okresu możesz podać
ExistingPeriodicWorkPolicy
który obsługuje 2 opcje: REPLACE
i KEEP
. Te opcje działają tak samo
.
Obserwowanie swojej pracy
W dowolnym momencie po dodaniu zadań do kolejki możesz sprawdzić ich stan, wysyłając zapytanie
WorkManagera można użyć za pomocą instancji name
, id
lub powiązanej z nią tag
.
Kotlin
// by id workManager.getWorkInfoById(syncWorker.id) // ListenableFutureW<orkInfo<>/span> // by name workManager.getWorkInfosForUniqueWork("sync") // ListenableFutureL<istW<orkInfo<>/span> > // by tag workManager.getWorkInfosByTag("syncTag") // ListenableFutureL<istW<orkInfo<>/span> >
Java
// by id workManager.getWorkInfoById(syncWorker.id); // ListenableFutureW<orkInfo<>/span> // by name workManager.getWorkInfosForUniqueWork("sync"); // ListenableFutureL<istW<orkInfo<>/span> > // by tag workManager.getWorkInfosByTag("syncTag"); // ListenableFutureL<istW<orkInfo<>/span> >
Zapytanie zwraca
ListenableFuture
obiektu WorkInfo
, który zawiera
id
utworu, jego tagów,
bieżące State
oraz wszystkie dane wyjściowe
ustaw przez
Result.success(outputData)
.
Wariant LiveData
każdego z parametrów
pozwalają obserwować zmiany w WorkInfo
przez rejestrację
słuchaczem. Jeśli na przykład chcesz wyświetlać użytkownikowi wiadomość, gdy
niektóre zadania zakończą się pomyślnie, możesz skonfigurować ustawienia w następujący sposób:
Kotlin
workManager.getWorkInfoByIdLiveData(syncWorker.id) .observe(viewLifecycleOwner) { workInfo - > if(workInfo?.state == WorkInfo.State.SUCCEEDED) { Snackbar.make(requireView(), R.string.work_completed, Snackbar.LENGTH_SHORT) .show() } }
Java
workManager.getWorkInfoByIdLiveData(syncWorker.id) .observe(getViewLifecycleOwner(), workInfo - >{ if (workInfo.getState() != null && workInfo.getState() == WorkInfo.State.SUCCEEDED) { Snackbar.make(requireView(), R.string.work_completed, Snackbar.LENGTH_SHORT) .show(); } });
Złożone zapytania służbowe
WorkManager w wersji 2.4.0 lub nowszej obsługuje złożone zapytania w przypadku zadań w kolejce za pomocą
WorkQuery
obiektów. WorkQuery obsługuje
zapytania o pracę na podstawie kombinacji tagów, stanu i niepowtarzalnej nazwy utworu.
Z przykładu poniżej dowiesz się, jak znaleźć wszystkie tagi „syncTag”,
który jest w stanie FAILED
lub CANCELLED
i ma unikalną nazwę utworu
„preProcess” lub „sync”.
Kotlin
val workQuery = WorkQuery.Builder .fromTags(listOf("syncTag")) .addStates(listOf(WorkInfo.State.FAILED, WorkInfo.State.CANCELLED)) .addUniqueWorkNames(listOf("preProcess", "sync") ) .build() val workInfos: ListenableFutureL<istW<orkInfo >>= workManager.getWorkInfos(workQuery)
Java
WorkQuery workQuery = WorkQuery.Builder .fromTags(Arrays.asList("syncTag")) .addStates(Arrays.asList(WorkInfo.State.FAILED, WorkInfo.State.CANCELLED)) .addUniqueWorkNames(Arrays.asList("preProcess", "sync") ) .build(); ListenableFutureL<istW<orkInfo >>workInfos = workManager.getWorkInfos(workQuery);
Każdy składnik (tag, stan lub nazwa) w elemencie WorkQuery
jest AND
-ed z prefiksem
reszta. Każda wartość komponentu jest typu OR
. Na przykład: (name1 OR name2
OR ...) AND (tag1 OR tag2 OR ...) AND (state1 OR state2 OR ...)
.
WorkQuery
działa również z jego odpowiednikiem LiveData,
getWorkInfosLiveData()
Anulowanie i zatrzymywanie pracy
Jeśli nie potrzebujesz już zadań znajdujących się w kolejce, możesz o to poprosić.
ma zostać anulowana. Praca może zostać anulowana przez: name
, id
lub tag
i powiązane z nią.
Kotlin
// by id workManager.cancelWorkById(syncWorker.id) // by name workManager.cancelUniqueWork("sync") // by tag workManager.cancelAllWorkByTag("syncTag")
Java
// by id workManager.cancelWorkById(syncWorker.id); // by name workManager.cancelUniqueWork("sync"); // by tag workManager.cancelAllWorkByTag("syncTag");
W środku WorkManager sprawdza
State
utworu. Jeśli utwór to
już ukończone,
nic się nie dzieje. W przeciwnym razie stan utworu zmienia się na
CANCELLED
i zadanie
nie będzie w przyszłości działać. Dowolne
WorkRequest
zadania, które są zależne
w tej pracy
również CANCELLED
.
Obecnie działa RUNNING
odbiera połączenie z numerem
ListenableWorker.onStopped()
Zastąp tę metodę, aby obsłużyć potencjalne czyszczenie. Zobacz przystanki
Run Worker.
Zatrzymaj uruchomioną instancję roboczą
Istnieje kilka różnych powodów, dla których aplikacja Worker
może zostać zatrzymana przez WorkManagera:
- wyraźnie poprosiłeś o anulowanie subskrypcji (za pomocą połączenia telefonicznego,
WorkManager.cancelWorkById(UUID)
). - W przypadku unikalnego utworu
jednoznacznie dodano nowy element
WorkRequest
do kolejkiExistingWorkPolicy
zREPLACE
. Wcześniejsza subskrypcjaWorkRequest
zostanie natychmiast uznana za anulowana. - Ograniczenia zadania nie są już spełnione.
- System nakazał aplikacji zatrzymanie pracy z jakiegoś powodu. Może to spowodować może się zdarzyć, jeśli termin wykonania przekroczy 10 minut. Praca jest zaplanowano ponowienie próby w późniejszym czasie.
W tych warunkach instancja robocza zostanie zatrzymana.
Zakończ współpracę i przerwij prac zasoby, z których korzysta pracownik. Na przykład zamknij okno nicki do baz danych i plików. Istnieją 2 mechanizmy na poziomie aby zrozumieć, kiedy pracownik się zatrzymuje.
Wywołanie zwrotne onStopped()
WorkManager wywołuje
ListenableWorker.onStopped()
w momencie zatrzymania instancji roboczej. Zastąp tę metodę, aby zamknąć
wszystkie posiadane przez Ciebie zasoby.
właściwość isStopped(),
Możesz wywołać funkcję
ListenableWorker.isStopped()
, aby sprawdzić, czy instancja robocza została już zatrzymana. Jeśli
wykonując długotrwałe lub powtarzające się operacje w instancji roboczej,
często sprawdzaj tę właściwość i używaj jej jako sygnału do natychmiastowego przerwania pracy
jak to tylko możliwe.
Uwaga: WorkManager ignoruje wartość
Result
ustawione przez pracownika
które otrzymało sygnał onStop, ponieważ instancja robocza jest już brana pod uwagę
zatrzymano.