This is documentation for the next SDK version. For up-to-date documentation, see the latest version (SDK 52).
A library that provides an API for running background tasks.
expo-background-task
provides an API to run deferrable background tasks in a way that optimizes battery and power consumption on the end user's device. This module uses the WorkManager
API on Android and the BGTaskScheduler
API on iOS to schedule tasks. It also uses the expo-task-manager Native API to run JavaScript tasks.
A background task is a deferrable unit of work that is performed in the background, outside your app's lifecycle. This is useful for tasks that need to be executed when the app is inactive, such as syncing data with a server, fetching new content, or even checking if there are any expo-updates
.
The Expo Background Task API leverages each platform to execute tasks at the most optimal time for both the user and the device when the app is in the background.
This means that the task may not run immediately after it is scheduled, but it will run at some point in the future if the system decides so. You can specify a minimum interval in minutes for the task to run. The task will execute sometime after the interval has passed, provided the specified conditions are met.
A background task will only run if the battery has enough charge (or the device is plugged into power) and the network is available. Without these conditions, the task won't execute. The exact behavior will vary depending on the operating system.
Background tasks are managed by platform APIs and system constraints. Knowing when tasks stop helps plan their use effectively.
On Android, removing an app from the recent apps list doesn't completely stop it, whereas on iOS, swiping it away in the app switcher fully terminates it.
On Android, behavior varies by device vendor. For example, some implementations treat removing an app from the recent apps list as killing it. Read more about these differences here: https://dontkillmyapp.com.
On Android, the WorkManager
API allows specifying a minimum interval for a task to run (minimum 15 minutes). The task will execute sometime after the interval has passed, provided the specified conditions are met.
On iOS, the BGTaskScheduler
API decides the best time to launch your background task. The system will consider the battery level, the network availability, and the user's usage patterns to determine when to run the task. You can still specify a minimum interval for the task to run, but the system may choose to run the task at a later time.
The Background Tasks
API is unavailable on iOS simulators. It is only available when running on a physical device.
-
npx expo install expo-background-task
If you are installing this in an existing React Native app, start by installing expo
in your project. Then, follow the additional instructions as mentioned by the library's README under "Installation in bare React Native projects" section.
To be able to run background tasks on iOS, you need to add the processing
value to the UIBackgroundModes
array in your app's Info.plist file. This is required for background fetch to work properly.
If you're using CNG, the required UIBackgroundModes
configuration will be applied automatically by prebuild.
If you're not using Continuous Native Generation (CNG), then you'll need to add the following to your Info.plist file:
<key>UIBackgroundModes</key>
<array>
<string>processing</string>
</array>
</key>
Below is an example that demonstrates how to use expo-background-task
.
import * as BackgroundTask from 'expo-background-task';
import * as TaskManager from 'expo-task-manager';
import { useEffect, useState } from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
const BACKGROUND_TASK_IDENTIFIER = 'background-task';
// Register and create the task so that it is available also when the background task screen
// (a React component defined later in this example) is not visible.
// Note: This needs to be called in the global scope, not in a React component.
TaskManager.defineTask(BACKGROUND_TASK_IDENTIFIER, async () => {
try {
const now = Date.now();
console.log(`Got background task call at date: ${new Date(now).toISOString()}`);
} catch (error) {
console.error('Failed to execute the background task:', error);
return BackgroundTask.BackgroundTaskResult.Failed;
}
return BackgroundTask.BackgroundTaskResult.Success;
});
// 2. Register the task at some point in your app by providing the same name
// Note: This does NOT need to be in the global scope and CAN be used in your React components!
async function registerBackgroundTaskAsync() {
return BackgroundTask.registerTaskAsync(BACKGROUND_TASK_IDENTIFIER);
}
// 3. (Optional) Unregister tasks by specifying the task name
// This will cancel any future background task calls that match the given name
// Note: This does NOT need to be in the global scope and CAN be used in your React components!
async function unregisterBackgroundTaskAsync() {
return BackgroundTask.unregisterTaskAsync(BACKGROUND_TASK_IDENTIFIER);
}
export default function BackgroundTaskScreen() {
const [isRegistered, setIsRegistered] = useState<boolean>(false);
const [status, setStatus] = useState<BackgroundTask.BackgroundTaskStatus | null>(null);
useEffect(() => {
checkStatusAsync();
}, []);
const checkStatusAsync = async () => {
const status = await BackgroundTask.getStatusAsync();
setStatus(status);
};
const toggle = async () => {
if (isRegistered) {
await registerBackgroundTaskAsync();
} else {
await unregisterBackgroundTaskAsync();
}
setIsRegistered(!isRegistered);
};
return (
<View style={styles.screen}>
<View style={styles.textContainer}>
<Text>
Background Task Service Availability:{' '}
<Text style={styles.boldText}>
{status ? BackgroundTask.BackgroundTaskStatus[status] : null}
</Text>
</Text>
</View>
<Button
disabled={status === BackgroundTask.BackgroundTaskStatus.Restricted}
title={isRegistered ? 'Cancel Background Task' : 'Schedule Background Task'}
onPress={toggle}
/>
<Button title="Check Background Task Status" onPress={checkStatusAsync} />
</View>
);
}
const styles = StyleSheet.create({
screen: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
textContainer: {
margin: 10,
},
boldText: {
fontWeight: 'bold',
},
});
Since the Background Tasks API on iOS and the WorkManager API on Android limit the number of tasks that can be scheduled for a single app, Expo Background Task uses a single worker on both platforms. While you can define multiple JavaScript background tasks, they will all run through this single worker.
The last registered background task determines the minimum interval for execution.
import * as BackgroundTask from 'expo-background-task';
Returns the status for the Background Task API. On web, it always returns BackgroundTaskStatus.Restricted
,
while on native platforms it returns BackgroundTaskStatus.Available
.
Promise<BackgroundTaskStatus>
A BackgroundTaskStatus enum value or null
if not available.
Parameter | Type | Description |
---|---|---|
taskName | string | Name of the task to register. The task needs to be defined first - see |
options(optional) | BackgroundTaskOptions | An object containing the background task options. Default: {} |
Registers a background task with the given name. Registered tasks are saved in persistent storage and restored once the app is initialized.
Promise<void>
Example
import * as TaskManager from 'expo-task-manager';
// Register the task outside of the component
TaskManager.defineTask(BACKGROUND_TASK_IDENTIFIER, () => {
try {
await AsyncStorage.setItem(LAST_TASK_DATE_KEY, Date.now().toString());
} catch (error) {
console.error('Failed to save the last fetch date', error);
return BackgroundTaskResult.Failed;
}
return BackgroundTaskResult.Success;
});
You can now use the registerTaskAsync
function to register the task:
BackgroundTask.registerTaskAsync(BACKGROUND_TASK_IDENTIFIER, {});
Parameter | Type | Description |
---|---|---|
taskName | string | Name of the task to unregister. |
Unregisters a background task, so the application will no longer be executing this task.
Promise<void>
A promise which fulfils when the task is fully unregistered.
Options for registering a background task
Property | Type | Description |
---|---|---|
minimumInterval(optional) | number | Only for: Android Inexact interval in minutes between subsequent repeats of the background tasks. The final interval may differ from the specified one to minimize wakeups and battery usage.
|
Return value for background tasks.