Skip to content

// Background jobs done right — constraints, retries, chains, periodic work, expedited jobs, foreground service.

Android WorkManager Jobs

skill --stat
  • last update

    Jun 2, 2026

  • license

    MITv1.0.0

  • format

    SKILL.md

quickstart.sh
3 steps
  1. Install

    // Downloads SKILL.md into ~/.claude/skills/android-workmanager-jobs/

    $ curl -fsSL --create-dirs -o ~/.claude/skills/android-workmanager-jobs/SKILL.md https://claudeskil.com/skills/android-workmanager-jobs/SKILL.md
  2. Invoke

    // Inside Claude Code, type the skill name as a slash command

    > /android-workmanager-jobs help me ship this
  3. Or copy this from the README

    // extracted kotlin block

    $ @HiltWorker
    class UploadWorker @AssistedInject constructor(
        @Assisted ctx: Context,
        @Assisted params: WorkerParameters,
        private val repo: MediaRepo,
    ) : CoroutineWorker(ctx, params) {
android-workmanager-jobs/
references
SKILL.md
readonly
name:
Android WorkManager Jobs
slug:
android-workmanager-jobs
version:
v1.0.0
license:
MIT
author:
@chiragthummar16
categories:
tags:
#workmanager#background-jobs#kotlin#scheduling#hilt
description:

Background jobs done right — constraints, retries, chains, periodic work, expedited jobs, foreground service.

README.md

android-workmanager-jobs/README.md
6 sections

Android WorkManager Jobs

Production-grade scaffolding for deferrable background work on Android using Jetpack WorkManager. This skill helps you pick the right worker type, wire constraints and backoff correctly, inject dependencies into workers with Hilt, and test the whole thing deterministically. It's aimed at Android engineers who keep getting bitten by jobs that never run, run twice, or get killed under Doze.

When to use it

  • You need work to survive process death and reboots — uploads, log syncs, cache cleanup, DB compaction.
  • A task must wait for conditions: NetworkType.UNMETERED, charging, battery-not-low, or storage-not-low.
  • You're chaining steps where one worker's output feeds the next (compress → upload → notify).
  • You need a user-visible long task (large download) via an expedited/foreground job.
  • You're ripping out the deprecated Firebase JobDispatcher or GcmNetworkManager and consolidating on WorkManager.

How it works

The skill generates CoroutineWorker (or Worker) subclasses returning Result.success(), Result.retry(), or Result.failure(), plus the request builders that schedule them:

  • OneTimeWorkRequestBuilder vs PeriodicWorkRequestBuilder (15-minute minimum interval, optional flex window).
  • Constraints.Builder with setRequiredNetworkType, setRequiresCharging, etc.
  • Backoff via setBackoffCriteria(BackoffPolicy.EXPONENTIAL, ...).
  • Uniqueness with enqueueUniqueWork(... ExistingWorkPolicy.KEEP/REPLACE) and enqueueUniquePeriodicWork(... ExistingPeriodicWorkPolicy.UPDATE).
  • Chains through WorkManager.beginWith(a).then(b) and Data/workDataOf passing.
  • Hilt via @HiltWorker, @AssistedInject, and a HiltWorkerFactory registered through Configuration.Provider (disable the default initializer in the manifest).
  • Expedited jobs with setExpedited(OutOfQuotaPolicy...) and setForegroundAsync/getForegroundInfo.

Example

bash
curl -fsSL --create-dirs -o ~/.claude/skills/android-workmanager-jobs/SKILL.md https://claudeskil.com/skills/android-workmanager-jobs/SKILL.md
kotlin
@HiltWorker
class UploadWorker @AssistedInject constructor(
    @Assisted ctx: Context,
    @Assisted params: WorkerParameters,
    private val repo: MediaRepo,
) : CoroutineWorker(ctx, params) {
    override suspend fun doWork(): Result =
        runCatching { repo.upload(inputData.getString("uri")!!) }
            .fold({ Result.success() }, { if (runAttemptCount < 3) Result.retry() else Result.failure() })
}

val req = OneTimeWorkRequestBuilder<UploadWorker>()
    .setConstraints(Constraints.Builder().setRequiredNetworkType(NetworkType.UNMETERED).build())
    .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 30, TimeUnit.SECONDS)
    .build()
WorkManager.getInstance(ctx).enqueueUniqueWork("upload", ExistingWorkPolicy.KEEP, req)

Tips & gotchas

  • Periodic work can't be expedited and won't fire more often than every 15 minutes — the OS coalesces it.
  • If you use @HiltWorker, you must remove the default WorkManagerInitializer provider in the manifest, or the custom factory is ignored.
  • Read runAttemptCount to cap retries; Result.retry() alone loops forever under your backoff curve.
  • Expedited quota is finite — pick RUN_AS_NON_EXPEDITED_WORK_REQUEST as the fallback policy to avoid silent failures.

FAQ

Why does my unique periodic work not pick up new constraints? Use ExistingPeriodicWorkPolicy.UPDATE (API since WorkManager 2.8) so the request is replaced in place rather than kept.

How do I test workers without a real device clock? The skill scaffolds WorkManagerTestInitHelper.initializeTestWorkManager, then drives execution with TestDriver.setAllConstraintsMet, setPeriodDelayMet, and setInitialDelayMet.

Can I observe results? Yes — getWorkInfoByIdLiveData / getWorkInfosForUniqueWorkFlow expose WorkInfo.State and the output Data.

$ cat reviews/

Reviews

// No reviews yet. Be the first.
Loading review form…

$ ls related/

explore all →