Google is committed to advancing racial equity for Black communities. See how.

Debugging WorkManager

If you notice that your Workers run too often or not at all, here are a couple of debugging steps that can help to discover what might be going on.

Enable Logging

To determine why your Workers aren't running properly, it can be very useful to look at verbose WorkManager logs. To enable logging, you need to use custom initialization. First, disable the default WorkManagerInitializer in your AndroidManifest.xml:

<provider
    android:name="androidx.work.impl.WorkManagerInitializer"
    android:authorities="${applicationId}.workmanager-init"
    tools:node="remove" />

Notice that the manifest-merge rule remove is being used.

Now that the default initializer is disabled, you can use on-demand initialization. To do so, the android.app.Application class needs to provide an implementation for androidx.work.Configuration.Provider.

class MyApplication() : Application(), Configuration.Provider {
    override fun getWorkManagerConfiguration() =
        Configuration.Builder()
            .setMinimumLoggingLevel(android.util.Log.DEBUG)
            .build()
}

Once DEBUG logging is enabled, you will start seeing a lot more logs with the log-tag prefix WM-.

Use adb shell dumpsys jobscheduler

On API level 23 or higher, you can run the command adb shell dumpsys jobscheduler to look at the list of jobs which have been attributed to your package.

You should see something like this:

JOB #u0a172/4: 6412553 com.google.android.youtube/androidx.work.impl.background.systemjob.SystemJobService
  u0a172 tag=*job*/com.google.android.youtube/androidx.work.impl.background.systemjob.SystemJobService
  Source: uid=u0a172 user=0 pkg=com.google.android.youtube
  JobInfo:
    Service: com.google.android.youtube/androidx.work.impl.background.systemjob.SystemJobService
    Requires: charging=false batteryNotLow=false deviceIdle=false
    Extras: mParcelledData.dataSize=180
    Network type: NetworkRequest [ NONE id=0, [ Capabilities: NOT_METERED&INTERNET&NOT_RESTRICTED&TRUSTED&VALIDATED Uid: 10172] ]
    Minimum latency: +1h29m59s687ms
    Backoff: policy=1 initial=+30s0ms
    Has early constraint
  Required constraints: TIMING_DELAY CONNECTIVITY [0x90000000]
  Satisfied constraints: DEVICE_NOT_DOZING BACKGROUND_NOT_RESTRICTED WITHIN_QUOTA [0x3400000]
  Unsatisfied constraints: TIMING_DELAY CONNECTIVITY [0x90000000]
  Tracking: CONNECTIVITY TIME QUOTA
  Implicit constraints:
    readyNotDozing: true
    readyNotRestrictedInBg: true
  Standby bucket: RARE
  Base heartbeat: 0
  Enqueue time: -51m29s853ms
  Run time: earliest=+38m29s834ms, latest=none, original latest=none
  Last run heartbeat: 0
  Ready: false (job=false user=true !pending=true !active=true !backingup=true comp=true)

When using WorkManager, the component responsible for managing Worker execution is SystemJobService (on API level 23 or higher). You should look for instances of jobs which are attributed to your package name and androidx.work.impl.background.systemjob.SystemJobService.

For every job, the output from the command lists required, satisfied, and unsatisfied constraints. You should check to see if your Worker’s constraints are fully satisfied.

You can use this to check if SystemJobService was invoked recently. The output also includes job history for recently executed jobs:

Job history:
     -1h35m26s440ms   START: #u0a107/9008 com.google.android.youtube/androidx.work.impl.background.systemjob.SystemJobService
     -1h35m26s362ms  STOP-P: #u0a107/9008 com.google.android.youtube/androidx.work.impl.background.systemjob.SystemJobService app called jobFinished