androidandroid-workmanagerperiodic-task

WorkManager does not run more than 20 jobs


I am enqueuing future work while also running the initial job "now". After 20 items get enqueued any new items that get added no longer run immediately and I'm going to have to wait 30 days to see if they run at all ;)

I have waited more than 24 hours now after setting the initial delay for a work item as 10 seconds (the minimum allowed).

If I schedule a 21st job, nothing happens. Cancel any of the initial 20 and the 21st job runs after 10 seconds. 100% repeatable -- reschedule job 20, nothing. Cancel job 21 and job 20 will run after 10 seconds.

dependencies {
    implementation 'androidx.work:work-runtime:2.3.4'
}

fun scheduleTickle(context: Context, item: Item) {

    // item.id is the auto-generated primary key from the database

    val periodicWorkRequest = PeriodicWorkRequest.Builder(
        MessageWorker::class.java,
        item.minimumInterval,
        TimeUnit.DAYS
    ).let {
        it.setInputData(
            Data.Builder()
                .putLong("EXTRA_KEY_ITEM_ID", item.id)
                .build()
        )
        it.setConstraints(
            Constraints.Builder()
                .setRequiredNetworkType(NetworkType.CONNECTED)
                .build()
        )
        it.addTag("com.example.myapp.periodicWork.${item.id}")
        it.setInitialDelay(10, TimeUnit.SECONDS)
    }.build()

    WorkManager.getInstance(context).enqueueUniquePeriodicWork(
        item.id.toString(),
        ExistingPeriodicWorkPolicy.REPLACE,
        periodicWorkRequest
    )
}

Solution

  • I'm going to go out on a limb and guess that your question is:

    How can I have more jobs?

    The maximum number of jobs that WorkManager will register with JobScheduler or AlarmManager, by default, appears to be 20. The documentation is a bit odd, but the default value for setMaxSchedulerLimit() is MIN_SCHEDULER_LIMIT, which is 20.

    In principle, you should be able adjust that through the custom configuration process.

    However, there is an imposed upper limit of 50, if I am reading those docs correctly — in other words, you cannot pass a value higher than 50 to setMaxSchedulerLimit().

    Unless each of these pieces of work have completely independent criteria for execution, you might consider trying to consolidate some. For example, based on your code, you could use one job, with a time period of the lowest common denominator of the item.minimumInterval values, where part of the job's work is to see which of your actual things to do is ready to be executed.