WorkManager este o bibliotecă Jetpack pentru Android, concepută pentru executarea sarcinilor întârziate și de fundal cu garanție de execuție. Spre deosebire de Service sau JobScheduler, WorkManager preia gestionarea ciclului de viață al sarcinii: o repornește în caz de eșec, se adaptează la versiunea Android și ține cont de limitările dispozitivului. Conform Android Developers, 2026, WorkManager este soluția preferată pentru majoritatea operațiunilor de fundal în dezvoltarea modernă Android.
Principalul
WorkManager face parte din Android Jetpack, o bibliotecă pentru gestionarea sarcinilor de fundal care trebuie executate garantat, indiferent dacă aplicația este în prim-plan sau a fost închisă de utilizator. Biblioteca suportă API 14+ și alege automat mecanismul de execuție potrivit: JobScheduler pe Android 5+, BroadcastReceiver + AlarmManager pe versiunile mai vechi.
Caracteristica cheie a WorkManager este garanția de execuție. Dacă sarcina nu a fost finalizată din cauza repornirii dispozitivului, opririi aplicației sau unei erori, WorkManager o va reporni la prima ocazie. Acest lucru face din bibliotecă alegerea ideală pentru sarcini critice: trimitere de analitică, sincronizare bază de date, încărcare fișiere.
Spre deosebire de Background Service, WorkManager nu necesită gestionarea firelor de execuție și a ciclului de viață. Biblioteca își creează singură un pool de fire, gestionează Doze Mode, ține cont de versiunea Android și oferă o API unitară indiferent de nivelul API. Lucrul cu corutine și RxJava este suportat prin CoroutineWorker și RxWorker.
WorkManager oferă suport încorporat pentru LiveData pentru urmărirea stării sarcinilor. Metoda getWorkInfoByIdLiveData returnează LiveData<WorkInfo>, care se actualizează la fiecare schimbare de stare: ENQUEUED, RUNNING, SUCCEEDED, FAILED, CANCELLED. Acest lucru permite componentelor UI să reacționeze la schimbări fără interogarea manuală a planificatorului și fără scurgeri de memorie datorită componentelor 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()
}
}
Arhitectura WorkManager este construită în jurul a trei clase de bază: Worker, WorkRequest și WorkManager. Worker conține logica sarcinii, WorkRequest descrie parametrii de execuție, iar WorkManager gestionează coada și planificarea. Biblioteca folosește o bază de date internă Room pentru stocarea stării tuturor sarcinilor.
Worker este o clasă abstractă cu o singură metodă doWork, care este apelată într-un fir de fundal. Metoda returnează ListenableWorker.Result — SUCCESS, FAILURE sau RETRY. WorkRequest leagă Worker-ul de parametri: timeout, tag, întârziere inițială și constrângeri.
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 planifică sarcinile uniform, indiferent de versiunea Android. La apelul enqueue, biblioteca salvează sarcina în Room, evaluează condițiile curente și alege timpul optim de pornire. Sub capotă poate fi folosit JobScheduler, AlarmManager sau propriul planificator — dezvoltatorul nu trebuie să se gândească la asta.
val syncRequest = OneTimeWorkRequestBuilder<SyncWorker>()
.setInitialDelay(15, TimeUnit.MINUTES)
.addTag("sync")
.build()
WorkManager.getInstance(context)
.enqueue(syncRequest)
WorkManager suportă două tipuri de cereri de execuție: unice și periodice. Alegerea tipului depinde de scenariu: sarcina trebuie executată o dată sau repetată la un interval dat.
OneTimeWorkRequest este destinat sarcinilor care trebuie executate o singură dată. Poate fi trimiterea unui log, sincronizarea datelor după autentificare, încărcarea configurației la prima lansare. Întârzierea se setează prin setInitialDelay, iar constrângerile prin setConstraints.
PeriodicWorkRequest este potrivit pentru sarcini repetitive cu un interval minim de 15 minute. Biblioteca garantează că intervalul între executări nu va fi mai mic decât cel specificat, dar poate fi mai mare din cauza limitărilor dispozitivului. Pentru sarcini cu frecvență mai mică de 15 minute, folosește Handler sau Timer în Foreground Service.
| Parametru | OneTimeWorkRequest | PeriodicWorkRequest |
|---|---|---|
| Frecvență | unică | repetitivă (min. 15 min) |
| Cantitate | 1 execuție | până la anulare |
| Întârziere | setInitialDelay | setInitialDelay |
| Lanțuri | suportă | nu |
| Utilizare | încărcare, sincronizare | monitorizare, polling |
Constrângerile (constraints) în WorkManager permit stabilirea condițiilor în care sarcina poate fi pornită: conexiune la rețea (NetworkType), nivelul bateriei (batteryNotLow), starea stocării (StorageNotLow) și modul de așteptare (DeviceIdle). Sarcina nu va porni până când toate constrângerile nu sunt îndeplinite.
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresCharging(true)
.setRequiresBatteryNotLow(true)
.build()
val request = OneTimeWorkRequestBuilder<ImageUploadWorker>()
.setConstraints(constraints)
.build()
Lanțurile (chaining) permit organizarea executării secvențiale sau paralele a sarcinilor. beginWith pornește lanțul, then adaugă următorul Worker, care se va executa după finalizarea cu succes a precedentului. Pentru executare paralelă se folosește workManager.enqueue(listOf(request1, request2)).
WorkManager.getInstance(context)
.beginWith(compressWorker)
.then(uploadWorker)
.then(cleanupWorker)
.enqueue()
// compress → upload → cleanup secvențial
JobScheduler a fost introdus în Android 5 (API 21) ca serviciu de sistem pentru planificarea sarcinilor de fundal. WorkManager a venit ca înlocuitor, oferind o API cross-platform cu migrare automată și capabilități suplimentare: lanțuri, garanție de execuție, tag-uri, monitorizarea stării prin LiveData.
La migrarea de la JobScheduler la WorkManager, trebuie să transformi JobService într-un Worker, să înlocuiești JobInfo cu WorkRequest, iar Context.getSystemService cu API-ul WorkManager. WorkManager rezolvă automat problemele de compatibilitate și gestionează Doze Mode mai corect decât implementarea manuală a JobScheduler. Pașii migrării: 1) creează o clasă Worker, 2) construiește WorkRequest cu aceleași condiții, 3) șterge JobService și JobInfo din cod și manifest.
WorkManager suportă conceptul de sarcini unice prin ExistingWorkPolicy. Dacă o sarcină cu numele specificat există deja, politica determină comportamentul: KEEP (nu crea una nouă), REPLACE (înlocuiește-o pe cea existentă), APPEND (adaugă la sfârșitul lanțului) și APPEND_OR_REPLACE. UniqueWorkRequest este convenabil pentru sarcini care nu trebuie duplicate: sincronizarea bazei de date, încărcarea configurației, trimiterea pachetului de analitică.
WorkManager.getInstance(context)
.enqueueUniqueWork(
"sync_data",
ExistingWorkPolicy.KEEP,
syncRequest
)
CoroutineWorker suportă mecanismul setProgress, permițând transmiterea rezultatelor intermediare ale executării sarcinii. Acest lucru este util pentru operațiuni lungi: încărcarea unui fișier mare, procesarea loturilor de imagini, migrarea bazei de date. UI se poate abona la actualizări prin getWorkInfosByTagLiveData și poate afișa progresul în timp real. Este disponibilă și metoda ForegroundInfo pentru pornirea Worker-ului ca Foreground Service cu notificare, dacă sarcina trebuie să fie vizibilă utilizatorului.
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 suportă transmiterea datelor între Worker-i prin InputData și OutputData. InputData se creează în etapa de construire a WorkRequest-ului prin Data.Builder și se transmite Worker-ului prin inputData. După execuție, Worker-ul creează OutputData prin workDataOf sau Data.Builder și îl returnează împreună cu Result.success(outputData). Următorul Worker din lanț primește outputData-ul precedentului ca inputData propriu. Datele sunt stocate în format cheie-valoare cu suport pentru tipurile de bază: String, Int, Long, Boolean, Double. Dimensiunea maximă a Data este de 10 KB.
În practică, multe proiecte folosesc WorkManager ca unic planificator de sarcini de fundal. Google recomandă migrarea tuturor JobService-urilor existente la WorkManager, în special în aplicațiile care suportă Android 4.4 (API 19) și inferior, unde JobScheduler nu este disponibil, iar WorkManager folosește un mecanism de rezervă prin AlarmManager și BroadcastReceiver. Pentru testare, WorkManager oferă TestListenableWorkerBuilder și TestWorkerBuilder, care permit testarea Worker-ilor în teste JUnit fără un planificator real.
Pentru testarea WorkManager, folosește TestListenableWorkerBuilder din AndroidX Test, care permite rularea Worker-ului într-un mediu izolat și verificarea Result-ului returnat. Biblioteca oferă suport complet pentru JUnit și Robolectric pentru testare unitară fără un planificator real. În general, WorkManager este potrivit pentru 80% din sarcinile în care anterior se foloseau Service sau JobScheduler.
Întrebări frecvente
Da, WorkManager garantează executarea chiar și după repornire. Biblioteca salvează toate sarcinile nefinalizate în baza de date Room și le restaurează cu ajutorul BroadcastReceiver, care se declanșează după încărcarea sistemului.
Worker funcționează într-un fir de fundal fără suport pentru corutine sau RxJava. CoroutineWorker folosește corutine Kotlin cu suport pentru funcții suspend și anulare în scopul corutinei. RxWorker lucrează cu Observable și Single, potrivit pentru lanțuri reactive.
Pentru anulare, folosește workManager.cancelWorkById(id) sau workManager.cancelAllWorkByTag("tag"). Biblioteca oferă și metoda cancelUniqueWork("name") pentru anularea sarcinilor unice cu numele specificat.
Intervalul minim pentru PeriodicWorkRequest este de 15 minute. Această limitare a fost stabilită de Google pentru a preveni consumul excesiv al bateriei. Dacă sarcina trebuie executată mai frecvent, folosește Foreground Service sau Handler cu timer.
Da, WorkManager suportă API 14+. Pe dispozitivele fără JobScheduler (sub API 21), biblioteca folosește o combinație de AlarmManager și BroadcastReceiver pentru planificarea sarcinilor. Acest lucru face din WorkManager o soluție universală pentru sarcini de fundal.
Concluzii
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și