WorkManager Implementation for Background Tasks in Android App

TRUETECH is engaged in the development, support and maintenance of iOS, Android, PWA mobile applications. We have extensive experience and expertise in publishing mobile applications in popular markets like Google Play, App Store, Amazon, AppGallery and others.
Development and support of all types of mobile applications:
Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1 servicesAll 1735 services
WorkManager Implementation for Background Tasks in Android App
Medium
~2-3 business days
FAQ
Our competencies:
Development stages
Latest works
  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1052
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    445

Implementing WorkManager for Background Tasks in Android Applications

WorkManager is the standard API for guaranteed background tasks: file uploads, data synchronization, analytics reporting. It's not a replacement for Coroutines for one-off operations—WorkManager is for tasks that must complete even if the application is killed or the device reboots.

Core Concepts

Worker / CoroutineWorker is the unit of work. WorkRequest is a task with configuration. WorkManager is the scheduler, implemented on top of JobScheduler (API 23+), AlarmManager (older versions), and Firebase JobDispatcher (if available). Selection is automatic.

CoroutineWorker is the preferred option for Kotlin:

class SyncWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {

    override suspend fun doWork(): Result {
        return try {
            val userId = inputData.getString(KEY_USER_ID) ?: return Result.failure()
            syncRepository.syncUser(userId)
            Result.success()
        } catch (e: IOException) {
            if (runAttemptCount < 3) Result.retry() else Result.failure()
        }
    }

    companion object {
        const val KEY_USER_ID = "user_id"
    }
}

runAttemptCount is the retry counter. Result.retry() combined with BackoffPolicy determines when WorkManager will retry the task.

Task Configuration

val syncRequest = OneTimeWorkRequestBuilder<SyncWorker>()
    .setInputData(workDataOf(SyncWorker.KEY_USER_ID to userId))
    .setConstraints(
        Constraints.Builder()
            .setRequiredNetworkType(NetworkType.CONNECTED)
            .setRequiresBatteryNotLow(true)
            .build()
    )
    .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 15, TimeUnit.MINUTES)
    .addTag("sync_task")
    .build()

WorkManager.getInstance(context).enqueueUniqueWork(
    "user_sync_$userId",
    ExistingWorkPolicy.KEEP,
    syncRequest
)

enqueueUniqueWork with ExistingWorkPolicy.KEEP prevents duplicate tasks if one with the same name is already active. Without this, a user tapping "Sync" twice launches two parallel workers.

Periodic Tasks

val periodicRequest = PeriodicWorkRequestBuilder<SyncWorker>(1, TimeUnit.HOURS)
    .setConstraints(
        Constraints.Builder()
            .setRequiredNetworkType(NetworkType.UNMETERED)
            .build()
    )
    .build()

WorkManager.getInstance(context).enqueueUniquePeriodicWork(
    "hourly_sync",
    ExistingPeriodicWorkPolicy.UPDATE,
    periodicRequest
)

The minimum interval for PeriodicWorkRequest is 15 minutes. Shorter intervals are ignored and the system runs by its own schedule. ExistingPeriodicWorkPolicy.UPDATE (introduced in WorkManager 2.8.0) updates the settings of an existing periodic task without canceling it.

Task Chains

WorkManager.getInstance(context)
    .beginUniqueWork("upload_chain", ExistingWorkPolicy.REPLACE,
        OneTimeWorkRequestBuilder<CompressWorker>().build()
    )
    .then(OneTimeWorkRequestBuilder<UploadWorker>().build())
    .then(OneTimeWorkRequestBuilder<NotifyWorker>().build())
    .enqueue()

If CompressWorker returns Result.failure(), the chain stops and UploadWorker doesn't run. Result.success(outputData) passes data to the next worker via inputMerger.

Observing Status

WorkManager.getInstance(context)
    .getWorkInfosByTagLiveData("sync_task")
    .observe(viewLifecycleOwner) { workInfos ->
        workInfos?.forEach { info ->
            when (info.state) {
                WorkInfo.State.RUNNING  -> showProgress()
                WorkInfo.State.SUCCEEDED -> showSuccess()
                WorkInfo.State.FAILED   -> showError()
                else -> Unit
            }
        }
    }

Common Project Issues

Tasks don't run on Chinese devices (Xiaomi, Huawei). Aggressive battery savers kill background processes. WorkManager uses JobScheduler, which these manufacturers override. The only reliable workaround is setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST) for time-critical tasks and documenting limitations in README. Guaranteeing precise background task execution time on these devices is impossible.

Context leaks. Worker receives applicationContext, but developers sometimes capture Activity in lambdas. Workers live longer than Activities—crashes occur when accessing destroyed contexts.

Too much data in inputData. The limit is 10 KB. Pass IDs, not serialized objects. Read data from Room or SharedPreferences inside the worker.

Integration with Hilt

@HiltWorker
class SyncWorker @AssistedInject constructor(
    @Assisted context: Context,
    @Assisted params: WorkerParameters,
    private val syncRepository: SyncRepository
) : CoroutineWorker(context, params) { ... }

// In Application
@HiltAndroidApp
class App : Application(), Configuration.Provider {
    @Inject lateinit var workerFactory: HiltWorkerFactory

    override fun getWorkManagerConfiguration() =
        Configuration.Builder().setWorkerFactory(workerFactory).build()
}

Without a custom Configuration.Provider, Hilt cannot inject dependencies into Worker—WorkManager creates workers using its default factory.

Implementing WorkManager with a basic task set takes 2–4 days. Complex chains with error handling, synchronization, and tests take up to 2 weeks. Cost is calculated individually.