JobIntentService doesn't start immediately on Android 8.0

Prudhvi picture Prudhvi · Oct 20, 2017 · Viewed 7.5k times · Source

I have implemented JobIntentService to do some background task which works fine on older Android devices (pre Android O). I see the intent is handled immediately but on Android O device there is some delay before JobIntentService.onHandleWork()is executed. I understand that intents are handled serially but I see the delay even if there are no intents being processed in the queue. Is it because job scheduling is handled internally in Android O?

Here, Android document says

"When running as a pre-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 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."

Is the above statement valid even if my app is targeted to API 25 but running on OS Android O? If so, is there any workaround to start the service/job immediately on Android O?

My current implementation:

public class MySampleService extends JobIntentService {

    private static final int JOB_ID = 1000;

    public MySampleService() {

    }

    /**
     * Convenience method for enqueuing work in to this service.
     */
    public static void enqueueWork(Context context, Intent work) {
        enqueueWork(context, MySampleService.class, JOB_ID, work);
    }

    /**
     * Interpret the incoming intent actions and handle it appropriately.
     * @param workIntent
     */
    @Override
    protected void onHandleWork(@NonNull Intent workIntent) {
        if(workIntent==null || workIntent.getAction() == null){
            return;
        }
        /* This gets printed immediately on pre Android O devices but not otherwise*/
        System.out.println("Intent Handled");
    }
}

Answer

CommonsWare picture CommonsWare · Oct 20, 2017

Is the above statement valid even if my app is targeted to API 25 but running on OS Android O?

Yes. JobIntentService behavior — using JobScheduler or not — is dictated by the version of Android that you are running on. Your targetSdkVersion has no impact.

If so, is there any workaround to start the service/job immediately on Android O?

Don't use JobIntentService. Use a regular foreground service. By definition, JobScheduler can schedule jobs as it sees fit, and there is no guarantee that it will execute a job immediately.