Photo by Mike Wilson on Unsplash

Keep those background Services working when targeting Android Oreo (26)

So you just started targeting Android Oreo and you have forgotten about thoses Services you created to update your widgets in the background.

You may or may not be aware that when you start targeting Android Oreo there are execution limits for background Services. In summary you can only start background Services from something that is considered to be in the foreground - foreground is defined in the link above. WidgetProviders are BroadcastReceivers for Widgets, therefore starting a Service from a WidgetProvider would be considered background.

These backgound execution limits do not affect Bound Services. If you declare a Bound Service, other components can bind to that service whether or not your app is in the foreground.

By now you have probably heard of the JobScheduler and you might be thinking you are going to have to refactor all your background Services to use this instead.

Well there is one very simple fix for you. JobIntentService.

The JobIntentService works in the same way as a Service however it enqueues the work into the JobScheduler on compatible Android targets. This means you can easily convert your Services and IntentServices into a JobIntentService and keep the same functionality. The JobIntentService also exposes a static method to start the service (`JobIntentService.enqueueWork()`). You may be wondering how this will work on versions of Android that do not currently support the JobScheduler. Well, part of the beauty of the JobIntentService is that it will handle compatibaility for you. If the app is running on a device lower than Android Oreo it will call Context.startService otherwise it will use the JobScheduler.

It’s so easy I can do this bit in snippets of Kotlin.

ExampleIntentService

ExampleJobIntentService

Done.

Just remember to register your service in the Manifest and add the BIND_JOB_SERVICE permission.

  • When running on Android Oreo devices the JobIntentService uses the JobScheduler. This will handle the Wake Locks for you. On any device pre Android Oreo, the JobIntentService will set up Wake Locks through the PowerManager, so make sure you require the `WAKE_LOCK` permission in your manifest.

` <uses-permission android:name=”android.permission.WAKE_LOCK” />`

  • When running on anything less than Android Oreo the service will start almost instantly. On Android Oreo it will be subject to JobScheduler policies, in other words it will not run while the device is dozing and may get delayed more than a usual service when the system is under heavy load.
  • On pre Android Oreo the service can run indefinitely but on Android Oreo it will adhere to the usual JobService execution type limits. At which point it will stop (not the process) and continue execution at a later time.

You can find more about the JobIntentService here.

Engineering Manager (Client Platforms) @Plex

The (retired) Pub(lication) for Android & Tech, focused on Development