JobScheduler, Job IDs, and Libraries
TL;DR: If you write an Android library, and it uses
JobScheduler to schedule
jobs, make sure that the job IDs that you use are configurable by the app that
is using your library.
Ori Wasserman asked a damn good question this morning (my time) on Stack Overflow:
According to the documentation, jobs must have a unique Job ID per uid. If I use a 3rd party library which also schedules jobs, does this mean I can’t use the same Job ID as theirs? If so, how can I avoid these kind of collisions?
(“aw, crap” moments like this are better than caffeine for waking me up…)
When you create a
JobInfo via a
JobInfo.Builder, you provide an
that serves as a unique ID for that job within all apps associated with your
Linux user ID. For most developers, that means that the ID is unique within
your app. The “associated with your Linux user ID” part is for developers
who are using
android:sharedUserId, which I sincerely hope is not being used
all that much outside of custom ROM developers.
However, since that ID is unique for the app, that would include being unique across both the app’s own code and the code from any library that the app uses. And that’s where the problem arises. I cannot see a good way to have everybody coordinate as to what the IDs are. And even if there is such a way, there is no requirement for all libraries to use that coordination point.
For example, you might think that we could use the
id resource trick: define
id resource for the job ID, and that
id value is guaranteed to be
unique within the resource identifier space. However:
The docs point out that the
idneeds to be stable across app updates, and therefore an
idresource is unsuitable
There is nothing forcing library authors to use an
If you are writing a library, while you are welcome to default the job IDs to
something (to simplify integration of your library), be sure to have some means
to allow the app to change those IDs. App developers, in turn, need to look
for library APIs related to job IDs and use them, if you are also using
elsewhere (in your app code or via yet more libraries).
As problems go, this one is not unique (pun intended). We also need unique
Notification IDs, for example. Similarly, if your library raises a
Notification, while you might default your notification ID to some value, be
sure to allow app developers to change that value to something else, to avoid conflicts
with other notification IDs used elsewhere in the app.
JobScheduler job ID issue was not a big deal. Partially,
that is because
JobScheduler is new to Android 5.0, and only recently has
Android 5.0+ gotten to over 50% market share. Partially, that is because
only so many apps and libraries needed to schedule jobs.
However, with the continued War on Background Processing by way of Android O,
JobScheduler becomes increasingly important:
You may find yourself using a job instead of an
IntentServicefor background work that might take more than a minute, but less than ten minutes, and for which you would prefer not to use a foreground service
JobSchedulerhas been touted as an alternative to implicit broadcasts, though in truth that only works in a few cases
I half expect O Developer Preview 3 to show how
JobScheduler can be used
both as a floor wax and as a dessert topping.
Regardless, the number of libraries needing
JobScheduler should climb steadily,
and with that comes the issue of job ID conflicts.
In general, anywhere in Android that requires some sort of app-defined unique identifier, library developers should consider offering control over those identifiers to the consumers of the library.
Learn second-generation Android app development — with Kotlin and the Android Jetpack — through CommonsWare’s Android app development training!