Oreo, Services, and Libraries

If you are developing reusable libraries for Android app developers, and those libraries have contained services, you may need to add some flexibility to your libraries, with an eye towards Android 8.0’s changes.

Specifically:

  • Consider making the service optional. Refactor the work performed by that service into a separate class, with a separate service wrapper. Allow developers to continue using your service or work directly with the separate class, with suitable warnings for how to use that separate class successfully.

  • If you determine that is impractical, at least give users of your library control over how the service is started (if it is a started service) and whether or not the service should be in the foreground.

For example, I discontinued my WakefulIntentService, as its functionality is largely superseded by JobIntentService. If I wanted to bring WakefulIntentService up to date, I would need to allow users of the library to indicate whether or not they intended for their WakefulIntentService to be a foreground service or not, so that I would use startForegroundService() instead of startService() to start the service. As it stands, WakefulIntentService uses startService(), and that will not work in many Android 8.0 scenarios.

Refactoring your service and extracting its business logic into a separate public class gives users of your library the flexibility to:

  • Continue using your existing service wrapper

  • Write their own service wrapper, deciding for themselves whether it is a foreground service or not

  • Wrap your code in a JobIntentService, if that will be more suitable

The worst-case scenario is where the library controls the service but has it behave in ways that run counter to the desires of users of the library:

  • You think that the service should be a foreground service, and some users of the library disagree

  • You think that the work should get done in less than a minute, so the existing code should be fine, and some users of the library have evidence to the contrary

  • You think that JobIntentService should cover the needs, and some users of the library are concerned about delays in the work being started on Android 8.0+ (due to the whims of JobScheduler scheduling)

Ideally, services inside of libraries would be implementation details, not impacting the library API. And, sometimes, that will be possible. Unfortunately, Android 8.0’s changes makes it more likely that your library’s API abstraction will need to be leaky, to accommodate Android 8.0’s background limitations.