Home

Awesome

Firebase JobDispatcher

Status: Archived

This repository has been archived and is no longer maintained.

status: inactive


Update: April 2019

Last year, we announced Android Jetpack WorkManager. WorkManager, the new job management system in Jetpack, incorporates the features of Firebase Job Dispatcher (FJD) and Android’s JobScheduler to provide a consistent job scheduling service back to api level 14 while leveraging JobScheduler on newer devices. WorkManager works with or without Google Play Services, which is something FJD cannot do. WorkManager was first released to alpha in May 2018 and then went thru extensive iteration and improvement based on developer feedback including 10 alphas; it moved to beta on Dec 19, 2018, and was released to stable on Mar 5, 2019. One thing the team has been discussing at some length is whether it would be better for developers in the long run if we create one holistic solution via WorkManager; where we can pool all of our efforts and also give developers a single unified recommended path?

After careful evaluation, the team has decided to focus all of our efforts on WorkManager and to deprecate Firebase Job Dispatcher. We have modified our plans in direct response to developer feedback in order to make this as easy for you as possible. We know that managing background work is a critical part of your app and these changes impact you. We want to support you through this migration as much as we can by giving you as much advance notice as possible to make these changes. Firebase Job Dispatcher will be archived in github in about 1 year, on Apr 7, 2020. Apps should migrate to WorkManager or an alternative job management system before this date.

We’ve created a detailed migration guide to assist you in the transition to WorkManager. After Apr 7, 2020, this github repository will be archived and support for FJD customer issues will stop. Additionally, FJD will stop working once your app starts targeting an Android version after Android Q.

We are continuing to invest in and add new features to WorkManager and welcome any feedback or feature requests.

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 14+) that have Google Play services installed.

Overview

What's a JobScheduler?

The JobScheduler is an Android system service available on API levels 21 (Lollipop)+. It provides an API for scheduling units of work (represented by JobService subclasses) that will be executed in your app's process.

Why is this better than background services and listening for system broadcasts?

Running apps in the background is expensive, which is especially harmful when they're not actively doing work that's important to the user. That problem is multiplied when those background services are listening for frequently sent broadcasts (android.net.conn.CONNECTIVITY_CHANGE and android.hardware.action.NEW_PICTURE are common examples). Even worse, there's no way of specifying prerequisites for these broadcasts. Listening for CONNECTIVITY_CHANGE broadcasts does not guarantee that the device has an active network connection, only that the connection was recently changed.

In recognition of these issues, the Android framework team created the JobScheduler. This provides developers a simple way of specifying runtime constraints on their jobs. Available constraints include network type, charging state, and idle state.

This library uses the scheduling engine inside Google Play services(formerly the GCM Network Manager component) to provide a backwards compatible (back to Gingerbread) JobScheduler-like API.

This I/O presentation has more information on why background services can be harmful and what you can do about them:

Android battery and memory optimizations

There's more information on upcoming changes to Android's approach to background services on the Android developer preview page.

Requirements

The FirebaseJobDispatcher currently relies on the scheduling component in Google Play services. Because of that, it won't work on environments without Google Play services installed.

Comparison to other libraries

LibraryMinimum APIRequires Google PlayService API<sup>1</sup>Custom retry strategies
Framework JobScheduler21NoJobSchedulerYes
Firebase JobDispatcher14YesJobSchedulerYes
evernote/android-job14No<sup>2</sup>CustomYes
Android WorkManager<sup>3</sup>14No<sup>2</sup>CustomYes

<sup><a name="fn1">1</a></sup> Refers to the methods that need to be implemented in the Service subclass.<br> <sup><a name="fn2">2</a></sup> Uses AlarmManager or JobScheduler to support API levels <= 21 if Google Play services is unavailable.<br> <sup><a name="fn3">3</a></sup> Currently in alpha phase, soon to graduate to beta.</br>

Getting started

Installation

Add the following to your build.gradle's dependencies section:

implementation 'com.firebase:firebase-jobdispatcher:0.8.6'

Usage

Writing a new JobService

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("my-unique-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("my-unique-tag")
    // one-off job
    .setRecurring(false)
    // don't persist past a device reboot
    .setLifetime(Lifetime.UNTIL_NEXT_BOOT)
    // start between 0 and 60 seconds from now
    .setTrigger(Trigger.executionWindow(0, 60))
    // 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("my-unique-tag");

Cancelling all jobs

dispatcher.cancelAll();
<!-- ## Next steps - Browse the [API documentation][] [API documentation]: TODO: put link here -->

Contributing

See the CONTRIBUTING.md file.

Support

This library is actively supported by Google engineers. If you encounter any problems, please create an issue in our tracker.

License

Apache, see the LICENSE file.