androidengineers.Book a session

Battery & Network Optimization

Choosing JobScheduler/WorkManager

article20 minMedium

WorkManager is built on top of JobScheduler (and AlarmManager for very old devices). For most apps, WorkManager is the right choice and you never need to touch JobScheduler directly. But understanding when each layer is appropriate matters for advanced use cases.

The Background Work API Stack

App code
   └── WorkManager          ← Use this for almost everything
         └── JobScheduler   ← WorkManager uses this on API 23+
               └── AlarmManager (fallback for pre-23, via WorkManager)

WorkManager: Use for 99% of Background Work

WorkManager's advantages over raw JobScheduler:

FeatureWorkManagerJobScheduler
API level14+21+
Kotlin/Coroutines supportBuilt-in (CoroutineWorker)No
Chaining jobsYesNo
Observing stateWorkInfo LiveData/FlowNo
Unique workYesNo (manual)
TestingExcellent test supportDifficult
Backoff policyBuilt-in exponentialManual

When to use WorkManager:

  • Sync operations that need to survive app death
  • File uploads/downloads
  • Database maintenance (cleanup, migration)
  • Analytics batch uploads
  • Any deferrable background work

JobScheduler: When to Use Directly

Only reach for JobScheduler directly when:

  1. You need exact timing at the system level — WorkManager adds a small indeterminate delay; JobScheduler still has a minimum ~15 minute window for periodic.
  2. You're building an SDK — WorkManager adds significant library weight (~1 MB); SDKs often use JobScheduler to avoid inflating consumers' APK.
  3. Very specific system triggers — some triggers are available in JobScheduler but not exposed by WorkManager.
// Direct JobScheduler usage (for SDK authors)
val jobScheduler = context.getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler

val jobInfo = JobInfo.Builder(JOB_ID, ComponentName(context, MySyncJobService::class.java))
    .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
    .setRequiresBatteryNotLow(true)
    .setPersisted(true)  // survive reboot
    .setBackoffCriteria(30_000, JobInfo.BACKOFF_POLICY_EXPONENTIAL)
    .build()

jobScheduler.schedule(jobInfo)
class MySyncJobService : JobService() {
    private var syncJob: Job? = null

    override fun onStartJob(params: JobParameters): Boolean {
        syncJob = CoroutineScope(Dispatchers.IO).launch {
            try {
                performSync()
                jobFinished(params, false)   // false = don't reschedule
            } catch (e: IOException) {
                jobFinished(params, true)    // true = reschedule (retry)
            }
        }
        return true  // true = still processing (async)
    }

    override fun onStopJob(params: JobParameters): Boolean {
        syncJob?.cancel()
        return true  // true = reschedule this job
    }
}

AlarmManager: Almost Never Use Directly

AlarmManager schedules work at an exact time, even if the device is in Doze. It's the most battery-expensive option because it prevents the device from sleeping.

The only valid use case: User-visible alarms (alarm clock apps, reminder apps) that must fire at an exact time regardless of device state.

// Exact alarm (requires SCHEDULE_EXACT_ALARM permission, API 31+)
val alarmManager = getSystemService(AlarmManager::class.java)
alarmManager.setExactAndAllowWhileIdle(
    AlarmManager.RTC_WAKEUP,
    triggerTime,
    pendingIntent
)

Don't use AlarmManager for: data syncs, analytics, background polls. Use WorkManager instead.

Decision Flowchart

Does it need to fire at an exact clock time?
  └── Yes: AlarmManager (user-visible alarms only)
  └── No: Does your code run in an SDK?
        └── Yes + size matters: JobScheduler
        └── No: WorkManager

Key Takeaways

APIWhen to use
WorkManagerAll deferrable background work; almost everything
JobSchedulerSDK authors who can't afford WorkManager's size
AlarmManagerExact-time alarms for user-facing alarm apps only

YOUR LEARNING JOURNEY

0 of 177 available lessons completed

Progress saved in this browser. No account needed.
Choosing JobScheduler/WorkManager | Android System Design | Android Engineers