Working with Background Tasks
1. Using Task Manager
Example: Registering a Background Task
import * as TaskManager from 'expo-task-manager';
const BACKGROUND_TASK_NAME = 'my-background-task';
TaskManager.registerTaskAsync(BACKGROUND_TASK_NAME, {
with: {
periodic: {
interval: 60 * 1000, // Run every minute
},
},
});
export default function BackgroundTask() {
return null;
}
| Property | Description | Values |
|---|---|---|
| name | Unique identifier for the task | string |
| with.periodic.interval | How often to run the task (in milliseconds) | number |
| with.ios | iOS-specific configuration options | object |
| with.android | Android-specific configuration options | object |
Note: Background tasks are subject to OS limitations and may not run at exact intervals.
Warning: Ensure your task completes within the allowed time to avoid termination.
2. Defining Background Tasks
| Property | Description | Values |
|---|---|---|
| taskName | Unique identifier for the background task | 'my-background-task' |
| executionTimeout | Maximum time (in ms) the task can run before being terminated | 30000 |
| isAvailable | Function to check if the task can be executed | () => true |
Example: Define a background task
import * as TaskManager from 'expo-task-manager';
const TASK_NAME = 'my-background-task';
TaskManager.defineTask(TASK_NAME, async ({ data, error, executionInfo }) => {
if (error) {
console.error('Background task error:', error);
return;
}
// Your background logic here
console.log('Executing background task:', data);
});
Note: Background tasks must be defined before they can be registered or scheduled.
Warning: Background tasks are subject to system limitations and may not execute immediately.
3. Registering Tasks
Example: Basic Task Registration
import * as TaskManager from 'expo-task-manager';
const TASK_NAME = 'my-background-task';
TaskManager.registerTaskAsync(TASK_NAME, {
with: {
interval: 60 * 1000, // Run every minute
repeat: true,
},
});
| Property | Description | Values |
|---|---|---|
| name | Unique identifier for the task | string |
| with | Configuration options for task execution | object |
| with.interval | How often to run the task (in milliseconds) | number |
| with.repeat | Whether to repeat the task | boolean |
Note: Background tasks must be registered before they can be executed. The task name should be unique across your app.
4. Unregistering Tasks
Unregistering background tasks is essential to prevent unnecessary resource consumption and ensure clean task management. Expo provides methods to unregister tasks either by their ID or by type.
| Method | Description | Notes |
|---|---|---|
| TaskManager.unregisterTaskAsync(taskId) | Unregisters a specific task by its ID | Must be called with the exact task ID as registered |
| TaskManager.unregisterAllTasksAsync() | Unregisters all currently registered tasks | Useful for cleaning up before app shutdown or reset |
Example: Unregistering a Specific Task
import * as TaskManager from 'expo-task-manager';
const taskId = 'my-background-task';
await TaskManager.unregisterTaskAsync(taskId);
console.log('Task unregistered');
Example: Unregister All Tasks
import * as TaskManager from 'expo-task-manager';
await TaskManager.unregisterAllTasksAsync();
console.log('All tasks unregistered');
5. Using Background Fetch
| Property | Description | Default | Notes |
|---|---|---|---|
| backgroundFetch | Enables background fetch capability | false |
Set to true to enable background fetch |
| minInterval | Minimum interval in seconds between fetches | 300 |
Minimum is 300 seconds (5 minutes) |
Note: Background fetch is subject to OS-level limitations and may not run at the specified interval.
Warning: Ensure your app handles fetch failures gracefully to maintain user experience.
6. Implementing Location Tasks
| Property | Description | Values |
|---|---|---|
| taskName | Unique identifier for the background task | 'location-task' |
| interval | How often the task runs (in milliseconds) | 30000 |
| accuracy | Accuracy level of location data | 10 |
Example: Registering a Location Task
import * as TaskManager from 'expo-task-manager';
const LOCATION_TASK_NAME = 'background-location-task';
TaskManager.defineTask(LOCATION_TASK_NAME, async ({ data, error }) => {
if (error) {
console.error(error);
return;
}
console.log('Received data:', data);
});
export default function App() {
return (
<View style={styles.container}>
<Text>Background location task registered</Text>
</View>
);
}
Note: Ensure you have the necessary permissions in your app's manifest or configuration files.
Warning: Background tasks may be limited by device battery optimization settings.
7. Using Geofencing
| Property | Description | Values |
|---|---|---|
| region | Defines the geographic area to monitor | { latitude: number, longitude: number, radius: number } |
| onEnter | Callback when entering the region | () => void |
| onExit | Callback when exiting the region | () => void |
Example: Setting up a Geofence
import * as Location from 'expo-location';
const region = {
latitude: 37.7849,
longitude: -122.409,
radius: 100
};
const handleEnter = () => {
console.log("Entered geofenced area");
};
const handleExit = () => {
console.log("Exited geofenced area");
};
Location.watchPositionAsync(
{ accuracy: Location.Accuracy.High },
(position) => {
// Check if position is within region
const distance = calculateDistance(
position.coords.latitude,
position.coords.longitude,
region.latitude,
region.longitude
);
if (distance <= region.radius) {
handleEnter();
} else {
handleExit();
}
}
);
Note: Geofencing requires background location permissions and may have battery implications.
Warning: Accuracy of geofencing depends on device capabilities and may not be precise in all environments.
8. Handling Task Execution
| Property | Description | Values |
|---|---|---|
| taskName | Name of the background task to execute | string |
| executionTime | Maximum time the task can run (in seconds) | number |
| priority | Priority level of the task execution | low | normal | high |
Example: Scheduling a Background Task
import * as TaskManager from 'expo-task-manager';
const taskName = 'my-background-task';
const executionTime = 30;
TaskManager.registerTaskAsync(taskName, {
executionTime,
priority: 'normal'
});
Note: Background tasks must be registered before they can be executed. Ensure the task name is unique and matches between registration and execution.
Warning: Tasks with high priority may impact device performance or battery life. Use sparingly and only when necessary.
9. Checking Task Status
| Property | Description | Values |
|---|---|---|
| taskId | Unique identifier for the task | string |
| status | Current status of the task | 'active', 'pending', 'finished', 'failed' |
| startTime | Timestamp when the task started | Date |
| endTime | Timestamp when the task ended | Date |
Example: Checking Task Status
import * as TaskManager from 'expo-task-manager';
const taskId = 'my-background-task';
const taskStatus = await TaskManager.getTaskStatusAsync(taskId);
console.log('Task Status:', taskStatus);
10. Managing Battery Optimization (Android)
| Property | Description | Default | Notes |
|---|---|---|---|
| backgroundTask | Identifier for the background task | null |
Used to uniquely identify the background task |
| taskName | Name of the background task | null |
Used to identify and manage the task in logs or UI |
| taskType | Type of background task (e.g., periodic, one-time) | periodic |
Defines how often the task runs |
Example: Registering a Background Task
import * as TaskManager from 'expo-task-manager';
const BACKGROUND_TASK_NAME = 'my-background-task';
TaskManager.registerTaskAsync(BACKGROUND_TASK_NAME, {
with: {
taskName: 'my-background-task',
taskType: TaskManager.TaskType.PERIODIC,
},
});
export default function App() {
return <View style={styles.container}></View>;
}
Note: On Android, background tasks may be subject to battery optimization restrictions. Ensure your app is configured to allow background execution.
Warning: Battery optimization can cause background tasks to be suspended or delayed. Users may need to manually disable battery optimization for your app in the device settings.
11. Configuring Minimum Interval
| Property | Values | Description |
|---|---|---|
| minimumInterval | 1000 |
Minimum interval in milliseconds between background task executions |
Example: Setting Minimum Interval
import * as TaskManager from 'expo-task-manager';
TaskManager.defineTask('my-background-task', async () => {
// Task logic here
});
// Configure minimum interval to 5 seconds
TaskManager.configure({
minimumInterval: 5000,
});
12. Handling Task Errors
| Error Type | Description | Handling Strategy |
|---|---|---|
| TaskError | Generic error thrown when a background task fails | Use try...catch around task execution to handle gracefully |
| TaskTimeoutError | Thrown when a task exceeds its timeout limit (default 30 seconds) | Implement custom timeout logic or increase taskTimeout in config |
| TaskCancellationError | Thrown when a task is cancelled before completion | Check isCancelled() or use AbortController to manage cancellation |
Example: Catching Task Errors
import { TaskManager } from 'expo-task-manager';
TaskManager.defineTask('my-background-task', async () => {
try {
await performBackgroundWork();
} catch (error) {
if (error.name === 'TaskTimeoutError') {
console.error('Task timed out:', error);
} else if (error.name === 'TaskCancellationError') {
console.log('Task was cancelled');
} else {
console.error('Unexpected task error:', error);
}
}
});
Note: Errors in background tasks do not crash the app but are logged to the console. Ensure proper error handling to prevent silent failures.