Does WorkManager have a cap to the number of jobs that run at the same time?
Very simple example:
- Click button, creating 10 one-time jobs
- Enqueue them all
- 3 jobs run at a time, instead of all 10 as expected
class MainActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
queue.setOnClickListener {
val jobs = mutableListOf<OneTimeWorkRequest>()
for( i in 1..10 ) {
jobs += OneTimeWorkRequestBuilder<MyWorker>()
.setInputData(workDataOf("key" to i))
.build()
}
WorkManager.getInstance().enqueue(jobs)
}
}
}
class MyWorker: Worker() {
override fun doWork(): Result {
val jobId = inputData.getInt("key", -1)
Log.d("worker", "starting job: $jobId")
Completable.timer(10, SECONDS).blockingGet()
Log.d("worker", "job finished: $jobId")
return SUCCESS
}
}
And the output:
08-30 14:03:10.392 9825 9855 D worker : starting job: 2
08-30 14:03:10.396 9825 9856 D worker : starting job: 3
08-30 14:03:10.400 9825 9854 D worker : starting job: 1
08-30 14:03:20.421 9825 9855 D worker : job finished: 2
08-30 14:03:20.421 9825 9856 D worker : job finished: 3
08-30 14:03:20.421 9825 9854 D worker : job finished: 1
08-30 14:03:20.442 9825 9856 D worker : starting job: 4
08-30 14:03:20.448 9825 9854 D worker : starting job: 5
08-30 14:03:20.450 9825 9855 D worker : starting job: 6
08-30 14:03:30.444 9825 9856 D worker : job finished: 4
08-30 14:03:30.449 9825 9854 D worker : job finished: 5
08-30 14:03:30.451 9825 9855 D worker : job finished: 6
08-30 14:03:30.474 9825 9856 D worker : starting job: 7
08-30 14:03:30.477 9825 9855 D worker : starting job: 8
08-30 14:03:30.480 9825 9854 D worker : starting job: 9
08-30 14:03:40.476 9825 9856 D worker : job finished: 7
08-30 14:03:40.478 9825 9855 D worker : job finished: 8
08-30 14:03:40.481 9825 9854 D worker : job finished: 9
08-30 14:03:40.497 9825 9856 D worker : starting job: 10
08-30 14:03:50.500 9825 9856 D worker : job finished: 10
The number of jobs that can run at the same time are actually determined by a thread pool that you configure. The default
Executor
is defined here.Typically when you are using the
Worker
base class, you are associating an instance of theWorker
to a thread on thisExecutor
. If you want greater control on which thread yourWorker
is associated with, you might want to take a look atCoroutineWorker
orListenableWorker
.The number of threads in the default
Executor
are determined by the number of cores on the device. If you want all 10 jobs to run at the same time you have to do the following:Disable the default
WorkManager
initializer (by disabling manifest merging for the content provider).Initialize
WorkManager
onApplication.onCreate()
or your ownContentProvider
. You need to do this here because the OS can ask previously scheduledWorker
s to run. For more information look at this.In the above example I am creating a fixed size thread pool with 10 threads (which in turn can handle 10
Workers
). Now when you enqueue yourWorker
s you will see all of them execute at the same time.