Schedule background jobs that run your JavaScript when your app is in the background.
The jobs will run even if the app has been closed and, by default, also persists over restarts.
This library relies on React Native's HeadlessJS
which is currently only supported on Android.
On the native side it uses either JobScheduler
or a Foreground Service.
-
JobScheduler (default): The jobs can't be scheduled exactly and for Android 23+ they fire at most once per 15 minutes +-5 minutes.
JobSceduler
is the most battery efficient way of scheduling background tasks. -
Foreground Service: Activated by setting
alwaysRunning
totrue
. This will show a notification which allows the app to run indefinitely without (almost) ever being killed by the system. This means that the intervals for triggering the jobs are much more exact and it can also be used for persistent tasks such as playing music. Currently only one background job can bealwaysRunning
, it won't throw any errors if you add more but it will only schedule one job.
- RN 0.36+
- Android API 21+
- Android
Want iOS? Go in and vote for Headless JS to be implemented for iOS: Product pains
$ yarn add react-native-background-job
or
$ npm install react-native-background-job --save
$ react-native link react-native-background-job
-
Open up
android/app/src/main/java/[...]/MainActivity.java
- Add
import com.pilloxa.backgroundjob.BackgroundJobPackage;
to the imports at the top of the file - Add
new BackgroundJobPackage()
to the list returned by thegetPackages()
method inMainApplication.java
- Add
-
Append the following lines to
android/settings.gradle
:include ':react-native-background-job' project(':react-native-background-job').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-background-job/android')
-
Insert the following lines inside the dependencies block in
android/app/build.gradle
and bump the minSdkVersion to 21:compile project(':react-native-background-job')
The jobs have to be registered each time React Native starts, this is done using the register
function. Since HeadlessJS does not mount any components the register
function must be run outside of any class definitions (see example/index.android.js)
Registering the job does not mean that the job is scheduled, it just informs React Native that this job
function should be tied to this jobKey
. The job is then scheduled using the schedule
function. The job will not fire while the app is in the foreground. This is since the job is run on the only JavaScript thread and if running the job when app is in the foreground it would freeze the app.
For a full example check out example/index.android.js
Registers jobs and the functions they should run.
This has to run on each initialization of React Native and it has to run in the global scope and not inside any
component life cycle methods. See example project. Only registering the job will not start running the job.
It has to be scheduled by schedule
to start running.
Parameters
obj
Object
Examples
import BackgroundJob from 'react-native-background-job';
const backgroundJob = {
jobKey: "myJob",
job: () => console.log("Running in background")
};
BackgroundJob.register(backgroundJob);
Schedules a new job.
This only has to be run once while register
has to be run on each initialization of React Native.
Parameters
obj
Objectobj.jobKey
string A unique key for the jobobj.timeout
number How long the JS job may run before being terminated by Android (in ms).obj.period
number? The frequency to run the job with (in ms). This number is not exact, Android may modify it to save batteries. Note: For Android > N, the minimum is 900 0000 (15 min). (optional, default900000
)obj.persist
boolean? If the job should persist over a device restart. (optional, defaulttrue
)obj.warn
boolean? If a warning should be raised if overwriting a job that was already scheduled. (optional, defaulttrue
)obj.networkType
number? Only run for specific network requirements, (not respected by pre Android N devices) docs (optional, defaultBackgroundJob.NETWORK_TYPE_NONE
)obj.requiresCharging
boolean? Only run job when device is charging, (not respected by pre Android N devices) docs (optional, defaultfalse
)obj.requiresDeviceIdle
boolean? Only run job when the device is idle, (not respected by pre Android N devices) docs (optional, defaultfalse
)obj.alwaysRunning
boolean? Creates a foreground service that will keep the app alive forever. Suitable for music playback etc. Will always show a notification. (optional, defaultfalse
)obj.notificationTitle
string The title of the persistent notification whenalwaysRunning
obj.notificationText
string The text of the persistent notification whenalwaysRunning
obj.notificationIcon
string The icon string (in drawable) of the persistent notification whenalwaysRunning
Examples
import BackgroundJob from 'react-native-background-job';
const backgroundJob = {
jobKey: "myJob",
job: () => console.log("Running in background")
};
BackgroundJob.register(backgroundJob);
var backgroundSchedule = {
jobKey: "myJob",
timeout: 5000
}
BackgroundJob.schedule(backgroundSchedule);
Fetches all the currently scheduled jobs
Parameters
obj
Objectobj.callback
function (Array) A list of all the scheduled jobs will be passed to the callback
Examples
import BackgroundJob from 'react-native-background-job';
BackgroundJob.getAll({callback: (jobs) => console.log("Jobs:",jobs)});
Cancel a specific job
Parameters
obj
Object
Examples
import BackgroundJob from 'react-native-background-job';
BackgroundJob.cancel({jobKey: 'myJob'});
Cancels all the scheduled jobs
Examples
import BackgroundJob from 'react-native-background-job';
BackgroundJob.cancelAll();
Sets the global warning level
Parameters
warn
boolean
Examples
import BackgroundJob from 'react-native-background-job';
BackgroundJob.setGlobalWarnings(false);
If you are using Android API +25 you can manually trigger the jobs by using the following command in a terminal:
$ adb shell cmd jobscheduler run -f your.package jobIntId
jobIntId
: is the hashed jobKey
. Get that value by going to Java REPL and input:
"yourJobKey".hashCode();
// 1298333557
Make sure you call the register
function at the global scope (i.e. not in any component life cycle methods (render, iDidMount etc)). Since the components are not rendered in Headless mode if you run the register function there it will not run in the background and hence the library will not find which function to run.
See example project
This is a React Native issue, you can get around it by calling NativeModules.AppState.getCurrentAppState
directly instead.
My job always runs in the background even if i specified requiresCharging
, requiresDeviceIdle
or a specific networkType
This is an Android issue, it seems that you can not have these restrictions at the same time as you have a periodic interval for pre Android N devices.