WorkManager to biblioteka Jetpack dla Androida przeznaczona do wykonywania opóźnionych i tła zadań z gwarancją wykonania. W przeciwieństwie do Service lub JobScheduler, WorkManager przejmuje zarządzanie cyklem życia zadania: uruchamia je ponownie w przypadku awarii, dostosowuje się do wersji Androida i uwzględnia ograniczenia urządzenia. Według Android Developers, 2026, WorkManager jest preferowanym rozwiązaniem dla większości operacji tła w nowoczesnym programowaniu Android.
Najważniejsze
WorkManager to część Android Jetpack, biblioteka do zarządzania zadaniami tła, które muszą zostać wykonane z gwarancją, niezależnie od tego, czy aplikacja jest na pierwszym planie, czy została zamknięta przez użytkownika. Biblioteka obsługuje API 14+ i automatycznie wybiera odpowiedni mechanizm wykonania: JobScheduler na Android 5+, BroadcastReceiver + AlarmManager na starszych wersjach.
Kluczową cechą WorkManager jest gwarancja wykonania. Jeśli zadanie nie zostało ukończone z powodu restartu urządzenia, zatrzymania aplikacji lub błędu, WorkManager uruchomi je ponownie przy pierwszej możliwej okazji. To czyni bibliotekę idealnym wyborem dla zadań krytycznych: wysyłanie analityki, synchronizacja bazy danych, przesyłanie plików.
W przeciwieństwie do Background Service, WorkManager nie wymaga zarządzania wątkami i cyklem życia. Biblioteka sama tworzy pulę wątków, obsługuje Doze Mode, uwzględnia wersję Androida i zapewnia jednolity API niezależnie od poziomu API. Praca z korutynami i RxJava jest obsługiwana przez CoroutineWorker i RxWorker.
WorkManager zapewnia wbudowane wsparcie LiveData do śledzenia stanu zadań. Metoda getWorkInfoByIdLiveData zwraca LiveData<WorkInfo>, która aktualizuje się przy każdej zmianie stanu: ENQUEUED, RUNNING, SUCCEEDED, FAILED, CANCELLED. Pozwala to komponentom UI reagować na zmiany bez ręcznego odpytywania harmonogramu i bez wycieków pamięci dzięki komponentom Lifecycle-aware.
WorkManager.getInstance(context)
.getWorkInfoByIdLiveData(syncRequest.id)
.observe(viewLifecycleOwner) { workInfo ->
when (workInfo.state) {
WorkInfo.State.SUCCEEDED ->
showSuccess()
WorkInfo.State.FAILED ->
showError(workInfo.outputData)
else ->
showProgress()
}
}
Architektura WorkManager opiera się na trzech podstawowych klasach: Worker, WorkRequest i WorkManager. Worker zawiera logikę zadania, WorkRequest opisuje parametry wykonania, a WorkManager zarządza kolejką i harmonogramem. Biblioteka używa wewnętrznej bazy danych Room do przechowywania stanu wszystkich zadań.
Worker to abstrakcyjna klasa z jedyną metodą doWork, która jest wywoływana w wątku tła. Metoda zwraca ListenableWorker.Result — SUCCESS, FAILURE lub RETRY. WorkRequest łączy Workera z parametrami: limitem czasu, tagiem, początkowym opóźnieniem i ograniczeniami.
class SyncWorker(
context: Context,
params: WorkerParameters
) : Worker(context, params) {
override fun doWork(): Result {
return try {
val api = RetrofitClient.api
val response = api.syncData()
Result.success()
} catch (e: Exception) {
Result.retry()
}
}
}
WorkManager jednolicie planuje zadania niezależnie od wersji Androida. Przy wywołaniu enqueue biblioteka zapisuje zadanie w Room, ocenia bieżące warunki i wybiera optymalny czas uruchomienia. Pod maską może być używany JobScheduler, AlarmManager lub własny harmonogram — programista się tym nie martwi.
val syncRequest = OneTimeWorkRequestBuilder<SyncWorker>()
.setInitialDelay(15, TimeUnit.MINUTES)
.addTag("sync")
.build()
WorkManager.getInstance(context)
.enqueue(syncRequest)
WorkManager obsługuje dwa typy zapytań wykonania: jednorazowe i okresowe. Wybór typu zależy od scenariusza: zadanie ma być wykonane raz lub powtarzać się w określonym interwale.
OneTimeWorkRequest jest przeznaczony do zadań, które mają być wykonane jednorazowo. Może to być wysłanie logów, synchronizacja danych po autoryzacji, pobranie konfiguracji przy pierwszym uruchomieniu. Opóźnienie ustawia się przez setInitialDelay, a ograniczenia przez setConstraints.
PeriodicWorkRequest nadaje się do powtarzalnych zadań z minimalnym interwałem 15 minut. Biblioteka gwarantuje, że interwał między uruchomieniami nie będzie mniejszy niż określony, ale może być dłuższy z powodu ograniczeń urządzenia. Dla zadań z częstotliwością mniejszą niż 15 minut używaj Handler lub Timer w Foreground Service.
| Parametr | OneTimeWorkRequest | PeriodicWorkRequest |
|---|---|---|
| Częstotliwość | jednorazowo | cyklicznie (min. 15 min) |
| Ilość | 1 wykonanie | do anulowania |
| Opóźnienie | setInitialDelay | setInitialDelay |
| Łańcuchy | obsługiwane | nie |
| Zastosowanie | pobieranie, synchronizacja | monitorowanie, polling |
Ograniczenia (constraints) w WorkManager pozwalają określić warunki, przy których zadanie może zostać uruchomione: połączenie sieciowe (NetworkType), poziom baterii (batteryNotLow), stan pamięci (StorageNotLow) i tryb czuwania (DeviceIdle). Zadanie nie uruchomi się, dopóki wszystkie ograniczenia nie zostaną spełnione.
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresCharging(true)
.setRequiresBatteryNotLow(true)
.build()
val request = OneTimeWorkRequestBuilder<ImageUploadWorker>()
.setConstraints(constraints)
.build()
Łańcuchy (chaining) umożliwiają sekwencyjne lub równoległe wykonywanie zadań. beginWith uruchamia łańcuch, then dodaje kolejnego Workera, który wykona się po pomyślnym zakończeniu poprzedniego. Do równoległego wykonania używa się workManager.enqueue(listOf(request1, request2)).
WorkManager.getInstance(context)
.beginWith(compressWorker)
.then(uploadWorker)
.then(cleanupWorker)
.enqueue()
// compress → upload → cleanup sekwencyjnie
JobScheduler został wprowadzony w Androidzie 5 (API 21) jako systemowa usługa harmonogramowania zadań tła. WorkManager przyszedł jako następca, oferując międzyplatformowy API z automatyczną migracją i dodatkowymi możliwościami: łańcuchy, gwarancja wykonania, tagi, obserwacja stanu przez LiveData.
Przy migracji z JobScheduler na WorkManager należy przekształcić JobService w Workera, zastąpić JobInfo na WorkRequest, a Context.getSystemService na API WorkManager. WorkManager automatycznie rozwiązuje problemy kompatybilności i lepiej obsługuje Doze Mode niż ręczna implementacja JobScheduler. Kroki migracji: 1) utwórz klasę Workera, 2) zbuduj WorkRequest z tymi samymi warunkami, 3) usuń JobService i JobInfo z kodu i manifestu.
WorkManager obsługuje koncepcję unikalnych zadań poprzez ExistingWorkPolicy. Jeśli zadanie o podanej nazwie już istnieje, polityka określa zachowanie: KEEP (nie twórz nowego), REPLACE (zastąp istniejące), APPEND (dodaj na koniec łańcucha) i APPEND_OR_REPLACE. UniqueWorkRequest jest wygodny dla zadań, które nie powinny się dublować: synchronizacja bazy danych, pobranie konfiguracji, wysyłanie paczki analityki.
WorkManager.getInstance(context)
.enqueueUniqueWork(
"sync_data",
ExistingWorkPolicy.KEEP,
syncRequest
)
CoroutineWorker obsługuje mechanizm setProgress, umożliwiający przekazywanie pośrednich wyników wykonania zadania. Jest to przydatne dla długotrwałych operacji: pobieranie dużego pliku, wsadowe przetwarzanie obrazów, migracja bazy danych. UI może subskrybować aktualizacje przez getWorkInfosByTagLiveData i wyświetlać postęp w czasie rzeczywistym. Dostępna jest również metoda ForegroundInfo do uruchomienia Workera jako Foreground Service z powiadomieniem, jeśli zadanie ma być widoczne dla użytkownika.
class ProgressWorker(
context: Context,
params: WorkerParameters
) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
val total = 100
for (i in 1..total) {
setProgress(
workDataOf("progress" to i)
)
}
return Result.success()
}
}
WorkManager obsługuje przesyłanie danych między Workerami przez InputData i OutputData. InputData jest tworzona na etapie budowania WorkRequest przez Data.Builder i przekazywana do Workera przez inputData. Po wykonaniu Worker tworzy OutputData przez workDataOf lub Data.Builder i zwraca wraz z Result.success(outputData). Następny Worker w łańcuchu otrzymuje outputData poprzedniego jako swój inputData. Dane są przechowywane w formacie klucz-wartość z obsługą podstawowych typów: String, Int, Long, Boolean, Double. Maksymalny rozmiar Data to 10 KB.
W praktyce wiele projektów używa WorkManager jako jedynego harmonogramu zadań tła. Google zaleca migrację wszystkich istniejących JobService na WorkManager, szczególnie w aplikacjach obsługujących Android 4.4 (API 19) i nowsze, gdzie JobScheduler jest niedostępny, a WorkManager używa mechanizmu zastępczego przez AlarmManager i BroadcastReceiver. Do testowania WorkManager udostępnia TestListenableWorkerBuilder i TestWorkerBuilder, które pozwalają testować Workerów w testach JUnit bez rzeczywistego harmonogramu.
Do testowania WorkManager używaj TestListenableWorkerBuilder z AndroidX Test, który umożliwia uruchamianie Workera w izolowanym środowisku i sprawdzanie zwracanego Result. Biblioteka zapewnia pełne wsparcie JUnit i Robolectric do testów jednostkowych bez rzeczywistego harmonogramu. Ogólnie WorkManager nadaje się do 80% zadań, w których wcześniej używano Service lub JobScheduler.
Często zadawane pytania
Tak, WorkManager gwarantuje wykonanie nawet po restarcie. Biblioteka przechowuje wszystkie niezakończone zadania w bazie danych Room i przywraca je za pomocą BroadcastReceiver, który uruchamia się po załadowaniu systemu.
Worker działa w wątku tła bez obsługi korutyn lub RxJava. CoroutineWorker używa korutyn Kotlin z obsługą funkcji suspend i anulowaniem w zakresie korutyny. RxWorker działa z Observable i Single, odpowiedni dla reaktywnych łańcuchów.
Do anulowania użyj workManager.cancelWorkById(id) lub workManager.cancelAllWorkByTag("tag"). Biblioteka udostępnia również metodę cancelUniqueWork("name") do anulowania unikalnych zadań o określonej nazwie.
Minimalny interwał dla PeriodicWorkRequest wynosi 15 minut. To ograniczenie zostało ustawione przez Google, aby zapobiec nadmiernemu zużyciu baterii. Jeśli zadanie ma być wykonywane częściej, użyj Foreground Service lub Handler z timerem.
Tak, WorkManager obsługuje API 14+. Na urządzeniach bez JobScheduler (poniżej API 21) biblioteka używa kombinacji AlarmManager i BroadcastReceiver do harmonogramowania zadań. To czyni WorkManager uniwersalnym rozwiązaniem dla zadań tła.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również