Reference version

This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.

Expo BackgroundFetch

一个用于执行后台提取任务的库

Android
iOS
Recommended version:
~58.0.1

expo-background-fetch 提供了执行后台获取任务的 API,允许你在后台定期运行特定代码来更新应用。此模块在底层使用 TaskManager Native API。

已知问题 
iOS

BackgroundFetch 仅在应用处于后台时有效,如果应用已终止或设备重新启动则无效。你可以查看相关 GitHub issue了解更多详情。

在 iOS 上,BackgroundFetch 库要求你使用开发构建,因为 iOS Expo Go 应用未启用 Background Fetch。

安装

Terminal
- npx expo install expo-background-fetch
- yarn expo install expo-background-fetch
- pnpm expo install expo-background-fetch
- bun expo install expo-background-fetch

If you are installing this in an existing React Native app, make sure to install expo in your project.

配置 
iOS

为了能够在 iOS 上运行后台获取任务,你需要将 fetch 值添加到应用 Info.plist 文件中的 UIBackgroundModes 数组。后台获取要正常工作,这是必需的。

如果你使用的是 CNG,所需的 UIBackgroundModes 配置将由 prebuild 自动应用。

在 iOS 上手动配置 UIBackgroundModes

如果你不使用 Continuous Native Generation(CNG),或者你手动使用原生 ios 项目,则需要将以下内容添加到你的 Expo.plist 文件中:

ios/project-name/Supporting/Expo.plist
<key>UIBackgroundModes</key> <array> <string>fetch</string> </array>

使用

下面是一个演示如何使用 expo-background-fetch 的示例。

Background Fetch usage
import { useState, useEffect } from 'react'; import { StyleSheet, Text, View, Button } from 'react-native'; import * as BackgroundFetch from 'expo-background-fetch'; import * as TaskManager from 'expo-task-manager'; const BACKGROUND_FETCH_TASK = 'background-fetch'; // 1. Define the task by providing a name and the function that should be executed // Note: This needs to be called in the global scope (e.g outside of your React components) TaskManager.defineTask(BACKGROUND_FETCH_TASK, async () => { const now = Date.now(); console.log(`Got background fetch call at date: ${new Date(now).toISOString()}`); // Be sure to return the successful result type! return BackgroundFetch.BackgroundFetchResult.NewData; }); // 2. Register the task at some point in your app by providing the same name, // and some configuration options for how the background fetch should behave // Note: This does NOT need to be in the global scope and CAN be used in your React components! async function registerBackgroundFetchAsync() { return BackgroundFetch.registerTaskAsync(BACKGROUND_FETCH_TASK, { minimumInterval: 60 * 15, // 15 minutes stopOnTerminate: false, // android only, startOnBoot: true, // android only }); } // 3. (Optional) Unregister tasks by specifying the task name // This will cancel any future background fetch 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 unregisterBackgroundFetchAsync() { return BackgroundFetch.unregisterTaskAsync(BACKGROUND_FETCH_TASK); } export default function BackgroundFetchScreen() { const [isRegistered, setIsRegistered] = useState(false); const [status, setStatus] = useState<BackgroundFetch.BackgroundFetchStatus | null>(null); useEffect(() => { checkStatusAsync(); }, []); const checkStatusAsync = async () => { const status = await BackgroundFetch.getStatusAsync(); const isRegistered = await TaskManager.isTaskRegisteredAsync(BACKGROUND_FETCH_TASK); setStatus(status); setIsRegistered(isRegistered); }; const toggleFetchTask = async () => { if (isRegistered) { await unregisterBackgroundFetchAsync(); } else { await registerBackgroundFetchAsync(); } checkStatusAsync(); }; return ( <View style={styles.screen}> <View style={styles.textContainer}> <Text> Background fetch status:{' '} <Text style={styles.boldText}> {status && BackgroundFetch.BackgroundFetchStatus[status]} </Text> </Text> <Text> Background fetch task name:{' '} <Text style={styles.boldText}> {isRegistered ? BACKGROUND_FETCH_TASK : 'Not registered yet!'} </Text> </Text> </View> <View style={styles.textContainer}></View> <Button title={isRegistered ? 'Unregister BackgroundFetch task' : 'Register BackgroundFetch task'} onPress={toggleFetchTask} /> </View> ); } const styles = StyleSheet.create({ screen: { flex: 1, justifyContent: 'center', alignItems: 'center', }, textContainer: { margin: 10, }, boldText: { fontWeight: 'bold', }, });

触发后台获取

后台获取可能很难测试,因为它们可能不一致地发生。幸运的是,你可以在开发应用时手动触发后台获取。

对于 iOS,你可以在 macOS 上使用 Instruments 应用手动触发后台获取:

  1. 打开 Instruments 应用。可以通过 Spotlight(Cmd ⌘ + Space)搜索 Instruments 应用,或从 /Applications/Xcode.app/Contents/Applications/Instruments.app 打开
  2. 选择 Time Profiler
  3. 选择你的设备/模拟器,然后选择 Expo Go 应用
  4. 按下左上角的 Record 按钮
  5. 导航到 Document 菜单,然后选择 Simulate Background Fetch - Expo Go:

对于 Android,你可以将任务的 minimumInterval 选项设置为较小的数值,然后像这样将应用置于后台:

async function registerBackgroundFetchAsync() { return BackgroundFetch.registerTaskAsync(BACKGROUND_FETCH_TASK, { minimumInterval: 1 * 60, // task will fire 1 minute after app is backgrounded }); }

API

import * as BackgroundFetch from 'expo-background-fetch';

Methods

BackgroundFetch.getStatusAsync()

Android
iOS

Gets a status of background fetch.

Returns a promise which fulfils with one of BackgroundFetchStatus enum values.

BackgroundFetch.registerTaskAsync(taskName, options)

Android
iOS
ParameterTypeDescription
taskNamestring

Name of the task to register. The task needs to be defined first - see TaskManager.defineTask for more details.

options(optional)BackgroundFetchOptions

An object containing the background fetch options.

Default:{}

Registers background fetch task with given name. Registered tasks are saved in persistent storage and restored once the app is initialized.

Returns:
Promise<void>

Example

import * as BackgroundFetch from 'expo-background-fetch'; import * as TaskManager from 'expo-task-manager'; TaskManager.defineTask(YOUR_TASK_NAME, () => { try { const receivedNewData = // do your background fetch here return receivedNewData ? BackgroundFetch.BackgroundFetchResult.NewData : BackgroundFetch.BackgroundFetchResult.NoData; } catch (error) { return BackgroundFetch.BackgroundFetchResult.Failed; } });

BackgroundFetch.setMinimumIntervalAsync(minimumInterval)

Android
iOS
ParameterTypeDescription
minimumIntervalnumber

Number of seconds that must elapse before another background fetch can be called.


Sets the minimum number of seconds that must elapse before another background fetch can be initiated. This value is advisory only and does not indicate the exact amount of time expected between fetch operations.

Returns:
Promise<void>

A promise which fulfils once the minimum interval is set.

BackgroundFetch.unregisterTaskAsync(taskName)

Android
iOS
ParameterTypeDescription
taskNamestring

Name of the task to unregister.


Unregisters background fetch task, so the application will no longer be executing this task.

Returns:
Promise<void>

A promise which fulfils when the task is fully unregistered.

Interfaces

BackgroundFetchOptions

Android
iOS
PropertyTypeDescription
minimumInterval(optional)number

Inexact interval in seconds between subsequent repeats of the background fetch alarm. The final interval may differ from the specified one to minimize wakeups and battery usage.

  • On Android it defaults to 10 minutes,
  • On iOS it calls BackgroundFetch.setMinimumIntervalAsync behind the scenes and the default value is the smallest fetch interval supported by the system (10-15 minutes). Background fetch task receives no data, but your task should return a value that best describes the results of your background fetch work.
startOnBoot(optional)boolean
Only for: 
Android

Whether to restart background fetch events when the device has finished booting.

Default:false
stopOnTerminate(optional)boolean
Only for: 
Android

Whether to stop receiving background fetch events after user terminates the app.

Default:true

Enums

BackgroundFetchResult

Android
iOS

This return value is to let iOS know what the result of your background fetch was, so the platform can better schedule future background fetches. Also, your app has up to 30 seconds to perform the task, otherwise your app will be terminated and future background fetches may be delayed.

NoData

BackgroundFetchResult.NoData = 1

There was no new data to download.

NewData

BackgroundFetchResult.NewData = 2

New data was successfully downloaded.

Failed

BackgroundFetchResult.Failed = 3

An attempt to download data was made but that attempt failed.

BackgroundFetchStatus

Android
iOS

Denied

BackgroundFetchStatus.Denied = 1

The user explicitly disabled background behavior for this app or for the whole system.

Restricted

BackgroundFetchStatus.Restricted = 2

Background updates are unavailable and the user cannot enable them again. This status can occur when, for example, parental controls are in effect for the current user.

Available

BackgroundFetchStatus.Available = 3

Background updates are available for the app.

权限

Android

在 Android 上,此模块可能会在设备启动时监听。这对于继续执行使用 startOnBoot 启动的任务是必要的。它还会让即将进入空闲并快速休眠的设备保持“唤醒”,从而提高任务的可靠性。因此,RECEIVE_BOOT_COMPLETED 和 WAKE_LOCK 权限会自动添加。

Android permissionDescription

RECEIVE_BOOT_COMPLETED

Allows an application to receive the Intent.ACTION_BOOT_COMPLETED that is broadcast after the system finishes booting.

WAKE_LOCK

Allows using PowerManager WakeLocks to keep processor from sleeping or screen from dimming.