Why Android’s JobIntentService is Broken

Since Google released Android O (API level 26), background processing became very hard for the developers. Google also replaced IntentService which was very useful for immediate processing, with JobIntentService. They also don’t allow your app to register for many broadcast receivers and also does not allow you to start a background service. In this post, we will talk about the JobIntentService and how some device vendors are not allowing the JobIntentService to work as intended, and also it’s alternative for immediate processing in these devices.

What official documentation says


In android documentation of JobIntentService, it says:

There are a few important differences in behavior when running on Android O or later as a Job vs. pre-O:

When running as a post-O service, the act of enqueueing work will generally start the service immediately, regardless of whether the device is dozing or in other conditions. When running as a Job, it will be subject to standard JobScheduler policies for a Job with a JobInfo.Builder.setOverrideDeadline(long) of 0: the job will not run while the device is dozing, it may get delayed more than a service if the device is under strong memory pressure with lots of demand to run jobs.

When running as a pre-O service, the normal service execution semantics apply: the service can run indefinitely, though the longer it runs the more likely the system will be to outright kill its process, and under memory pressure one should expect the process to be killed even of recently started services. When running as a Job, the typical JobService execution time limit will apply, after which the job will be stopped (cleanly, not by killing the process) and rescheduled to continue its execution later. Job are generally not killed when the system is under memory pressure, since the number of concurrent jobs is adjusted based on the memory state of the device.

So basically, JobIntentService will perform similar to an IntentService in pre-O devices. This means they will execute immediately. But in Android O and above devices, it is not guaranteed that the jobIntentService starts immediately, instead start with the delay depending on the device’s condition. But, some phone manufacturers are deliberately delaying the job for better battery life (Like OnePlus, Mi, Huawei). But sometimes, the job is never called.

This is not something that you would want if you want to process the information immediately and don’t want the job to be canceled.
But, the problem is that there is really not an alternative for JobIntentService or IntentService which starts the processing immediately. Since you cannot start a background service if your app is in the background.

Workaround

The workaround that we have found so far is to start a LOW_IMPORTANCE foreground service (Since we can start a foreground service from the background), do that work, and then stop it. This will start immediately and there won’t be any delay.
We can call the foreground service from the background like this:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    context.startForegroundService(startIntent);
} else {
    context.startService(startIntent);
}

But the drawback is that the notification is shown for a small duration till the work is complete.

Maybe Google should put some restrictions on the device manufacturers on how to manage the background apps.

Let us know what you feel about the JobIntentService and if you are facing any problems regarding it in the comments below.

Leave a Reply