Android - Guide to Firebase JobDispatcher
This tutorial will guide you in how to use the Firebase Job Dispatcher API which is compatible with the JobScheduler API for scheduling background jobs in your Android app. Let’s explore this exciting API in detail.
Firebase Job dispatcher
The Firebase JobDispatcher is a library for scheduling background jobs in your Android app. It provides a JobScheduler-compatible API that works on all recent versions of Android (API level 9+). The only condition is that you must have Google Play services installed on the device to work with this API.
Problems with Background Services
Running services in the background is very expensive for the battery life of the device, which is especially harmful when they're not actually doing any work that's required for the user. That problem is increased when those background threads are listening for frequently sent broadcasts (like android.net.conn.CONNECTIVITY_CHANGE and android.hardware.action.NEW_PICTURE etc.). Even worse, there's no way of specifying constraints for these broadcasts. Listening for CONNECTIVITY_CHANGE broadcasts does not guarantee that the device has an active network connection, only that the connection was just changed.
Requirements
The FirebaseJobDispatcher currently depends on the scheduling component in Google Play services. Because of that, it won't work on environments without Google Play services present.
Comparison to other libraries
Library |
Minimum API |
Requires Google Play |
Service API1 |
Custom retry strategies |
Framework JobScheduler |
21 |
No |
JobScheduler |
Yes |
Firebase JobDispatcher |
9 |
Yes |
JobScheduler |
Yes |
14 |
No2 |
Custom |
Yes |
Setup the Dispatcher
Let’s start by setting up the app in our build.gradle. There are options for this. Either add 2 dependencies as shown:
compile 'com.google.android.gms:play-services-gcm'
compile 'com.firebase:firebase-jobdispatcher:0.5.0'
Otherwise add the following:
compile 'com.firebase:firebase-jobdispatcher-with-gcm-dep:0.5.0'
Usage
The simplest possible JobService:
import com.firebase.jobdispatcher.JobParameters;
import com.firebase.jobdispatcher.JobService;
public class MyJobService extends JobService {
@Override
public boolean onStartJob(JobParameters job) {
// Do some work here
return false; // Answers the question: "Is there still work going on?"
}
@Override
public boolean onStopJob(JobParameters job) {
return false; // Answers the question: "Should this job be retried?"
}
}
Adding it to the manifest
<service
android:exported="false"
android:name=".MyJobService">
<intent-filter>
<action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE"/>"
</intent-filter>
</service>
Creating a Dispatcher
// Create a new dispatcher using the Google Play driver.
FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(context));
Scheduling a simple job
Job myJob = dispatcher.newJobBuilder()
.setService(MyJobService.class) // the JobService that will be called
.setTag("discover-sdk-tag") // uniquely identifies the job
.build();
dispatcher.mustSchedule(myJob);
Scheduling a more complex job
Bundle myExtrasBundle = new Bundle();
myExtrasBundle.putString("some_key", "some_value");
Job myJob = dispatcher.newJobBuilder()
// the JobService that will be called
.setService(MyJobService.class)
// uniquely identifies the job
.setTag("discover-sdk-tag")
// one-off job
.setRecurring(false)
// don't persist past a device reboot
.setLifetime(Lifetime.UNTIL_NEXT_BOOT)
// start between 0 and 90 seconds from now
.setTrigger(Trigger.executionWindow(0, 90))
// don't overwrite an existing job with the same tag
.setReplaceCurrent(false)
// retry with exponential backoff
.setRetryStrategy(RetryStrategy.DEFAULT_EXPONENTIAL)
// constraints that need to be satisfied for the job to run
.setConstraints(
// only run on an unmetered network
Constraint.ON_UNMETERED_NETWORK,
// only run when the device is charging
Constraint.DEVICE_CHARGING
)
.setExtras(myExtrasBundle)
.build();
dispatcher.mustSchedule(myJob);
Cancelling a job
dispatcher.cancel("discover-sdk-tag");
Cancelling all jobs
dispatcher.cancelAll();
Firebase JobDispatcher vs JobScheduler vs GcmTaskService
Firebase Android JobDispatcher is a layer of abstraction around job scheduling engines on Android. And for now they only have one driver implementation for the GCM Network Manager. That means currently it behaves the same way that the GCM Network Manager behaves. Hopefully in the future more Drivers will be implemented.
There is at least one drawback to using JobScheduler. As of the writing of this post, it’s compatible only with an API level of 21 or higher, so check into the distribution of Android devices running various API levels. While there is technically no backport of JobScheduler, a similar tool is GCM Network Manager.
GCM Network Manager is essentially like Lollipop's JobScheduler, except it's available for older releases as well.
GCM (Google Cloud Messaging) Network Manager actually uses JobScheduler behind the scenes for API level 21 and higher, and features support for previous versions of Android with Google Play Services.
>>> From API level 21 forward, GCM Network Manager uses the framework’s JobScheduler.
It’s important to note when comparing GCM Network Manager to JobScheduler that application and Google Play Service updates will wipe out scheduled Services. The onInitializeTask()method of GcmTaskService can be overridden to be notified of this event and respond accordingly to reschedule the service.
Also, be aware that GCM Network Manager and JobScheduler were not built to perform tasks immediately or at a given time.
Additional: Sync Adapter
Sync Adapters were introduced with the intent of keeping Android devices and servers synchronised. Syncs could be triggered from data changes in either the server or device, or by elapsed time and time of day (pretty cool, huh). The system will try to batch outgoing syncs to preserve battery life, and transfers that are unable to run will queue up for transfer at some later time. The system will attempt syncs only when the device is connected to a network (that’s being pretty smart).
These concepts should sound pretty familiar by now. A nice optional feature included with Sync Adapters is the ability for users to see information about syncs and the ability to turn off syncing all together.
Sync Adapters often require quite a bit more work to set up than the previous methods we discussed. However, if an application already supports android users and uses Content Providers, a lot of the boilerplate work is already done.
Additional: Doze
Doze Mode was introduced in Android 6.0 as a way to optimise battery power while a user is away from their device for some time. Doze Mode is automatically enabled on devices running Android API level 23 and higher. It is not a scheduler that developers need to implement.
>>> Doze affects the other schedulers we have already discussed.
Doze Mode is enabled after a period of time under these conditions: the user’s screen has been off, the device has been stationary (no movements at all) and the device is not plugged for charging. When in Doze Mode, network access is suspended, the system ignores wake locks and standard alarms are deferred, including the running of Sync Adapters and JobSchedulers. There are maintenance windows that infrequently occur to allow all of these schedulers within the system to run at once, therefore preserving battery through infrequent and grouped network calls.
Conclusion
In this article, we’ve covered how to use the Firebase JobDispatcher API which is compatible with the JobScheduler API to schedule background jobs in your Android app. We also compared GCM Network Manager, JobScheduler and the Firebase JobDispatcher. Now you’re free to build better apps that will work excellently in the background as well as perform magical tasks all while remaining hidden.
Recent Stories
Top DiscoverSDK Experts
Compare Products
Select up to three two products to compare by clicking on the compare icon () of each product.
{{compareToolModel.Error}}
{{CommentsModel.TotalCount}} Comments
Your Comment