This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.
Expo BackgroundTask
一个提供用于运行后台任务的 API 的库。
expo-background-task 提供了一个 API,用于以优化终端用户设备电池和电量消耗的方式运行可延迟的后台任务。此模块在 Android 上使用 WorkManager API,在 iOS 上使用 BGTaskScheduler API 来安排任务。它还使用 expo-task-manager Native API 来运行 JavaScript 任务。

使用 expo-background-task 在后台同步数据、预取内容并运行延迟工作。
后台任务
后台任务是在后台执行、独立于应用生命周期之外的可延迟工作单元。这对于需要在应用处于非活动状态时执行的任务很有用,例如与服务器同步数据、获取新内容,甚至检查是否有任何 expo-updates。
后台任务何时运行?
Expo Background Task API 利用各个平台,在应用处于后台时,于对用户和设备而言最合适的时间执行任务。
这意味着任务可能不会在安排后立即运行,但如果系统决定运行,它会在未来某个时间运行。你可以指定任务运行的最小时间间隔(以分钟为单位)。在指定的时间间隔过去后,只要满足指定条件,任务就会在某个时间执行。
只有在电池电量充足(或设备已接通电源)且网络可用时,后台任务才会运行。不满足这些条件时,任务不会执行。具体行为会因操作系统而异。
后台任务何时会停止?
后台任务由平台 API 和系统限制管理。了解任务何时停止有助于有效规划其使用方式。
- 如果用户强制关闭应用,后台任务会停止。应用重启后,任务会恢复。
- 如果系统停止应用或设备重启,后台任务会恢复,并且应用会重新启动。
在 Android 上,从最近使用的应用列表中移除应用并不会完全停止应用;而在 iOS 上,在应用切换器中向上滑动关闭应用会完全终止应用。
信息 在 Android 上,具体行为因设备厂商而异。例如,某些实现会将从最近使用的应用列表中移除应用视为将其关闭。你可以在此处详细了解这些差异:https://dontkillmyapp.com。
平台差异
Android Android
在 Android 上,WorkManager API 允许为任务指定最小运行间隔(最少 15 分钟)。在指定的时间间隔过去后,只要满足指定条件,任务就会在某个时间执行。
iOS iOS
在 iOS 上,BGTaskScheduler API 会决定启动后台任务的最佳时间。系统会考虑电池电量、网络可用性和用户的使用模式,以确定何时运行任务。你仍然可以为任务指定最小运行间隔,但系统可能会选择在更晚的时间运行任务。
已知限制
iOS iOS
Background Tasks API 在 iOS 模拟器上不可用。它仅在实体设备上运行时可用。
安装
If you are installing this in an existing React Native app, make sure to install expo in your project.
在应用配置中进行配置 iOS
要在 iOS 上运行后台任务,需要将以下内容添加到应用的 Info.plist 文件中:
- 将
processing值添加到UIBackgroundModes数组中。这会启用后台处理功能。 - 添加包含
com.expo.modules.backgroundtask.processing标识符的BGTaskSchedulerPermittedIdentifiers数组。这会注册允许使用的后台任务标识符。
如果你使用的是 CNG,prebuild 会自动应用所需的 UIBackgroundModes 和 BGTaskSchedulerPermittedIdentifiers 配置。
在 iOS 上手动配置 Info.plist
如果你未使用 Continuous Native Generation(CNG),则需要将以下内容添加到应用的 Info.plist 文件中:
使用
下面的示例演示了如何使用 expo-background-task。
多个后台任务
由于 iOS 上的 Background Tasks API 和 Android 上的 WorkManager API 限制了单个应用可安排的任务数量,因此 Expo Background Task 在两个平台上都使用单个 worker。虽然你可以定义多个 JavaScript 后台任务,但它们都会通过此单个 worker 运行。
最后注册的后台任务决定执行的最小时间间隔。
测试后台任务
可以使用 triggerTaskWorkerForTestingAsync 方法测试后台任务。此方法会在 Android 上直接运行所有已注册的任务,并在 iOS 上调用 BGTaskScheduler。这对于测试后台任务的行为很有用,无需等待系统触发这些任务。
此方法仅在开发模式下可用。在生产构建中无法使用。
import * as BackgroundTask from 'expo-background-task'; import { Button } from 'react-native'; function App() { const triggerTask = async () => { await BackgroundTask.triggerTaskWorkerForTestingAsync(); }; return <Button title="Trigger background task" onPress={triggerTask} />; }
检查后台任务 Android
要排查或调试 Android 上的后台任务问题,请使用 Android SDK 中包含的 adb 工具检查已安排的任务,并将 <package-name> 替换为应用配置中的 Android package name:
此命令的输出会显示应用已安排的任务,包括其状态、约束和其他信息。在输出中查找 JOB 行,以找到作业的 ID 和其他详细信息:
JOB #u0a453/275: 216a359 <package-name>/androidx.work.impl.background.systemjob.SystemJobService u0a453 tag=*job*/<package-name>/androidx.work.impl.background.systemjob.SystemJobService#275 Source: uid=u0a453 user=0 pkg=<package-name> ... Required constraints: TIMING_DELAY CONNECTIVITY UID_NOT_RESTRICTED [0x90100000] Preferred constraints: Dynamic constraints: Satisfied constraints: CONNECTIVITY DEVICE_NOT_DOZING BACKGROUND_NOT_RESTRICTED TARE_WEALTH WITHIN_QUOTA UID_NOT_RESTRICTED [0x1b500000] Unsatisfied constraints: TIMING_DELAY [0x80000000] ... Enqueue time: -8m12s280ms Run time: earliest=+6m47s715ms, latest=none, original latest=none Restricted due to: none. Ready: false (job=false user=true !restricted=true !pending=true !active=true !backingup=true comp=true)
第一行包含 Job ID(275)。Run time: earliest 值表示任务可能开始的最早时间,而 enqueue time 则显示任务已安排了多长时间。
要强制运行任务,请使用 adb shell am broadcast 命令。运行此命令前,请将应用切换到后台,因为应用处于前台时任务不会运行。
其中,JOB_ID 是你希望运行的作业的标识符,该标识符可以在上一步中找到。
排查后台任务问题 iOS
iOS 没有类似 adb 的工具来检查后台任务。要在 iOS 上测试后台任务,请使用内置的 triggerTaskWorkerForTestingAsync 方法。此方法会模拟系统触发任务。
你可以在调试模式下从应用中触发此方法(在生产构建中无法使用),以便在无需等待系统的情况下测试后台任务的行为。如果后台任务配置不正确,你会在 Xcode 控制台中看到错误描述:
No task request with identifier com.expo.modules.backgroundtask.processing has been scheduled
上述错误表示你需要运行 prebuild,以将更改应用到应用配置中。
此错误还表示你必须运行 prebuild,将后台任务配置应用到应用中。此外,请确保已按照此示例定义并注册后台任务。
API
import * as BackgroundTask from 'expo-background-task';
Methods
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.
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, async () => { 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, {});
When in debug mode this function will trigger running the background tasks. This function will only work for apps built in debug mode. This method is only available in development mode. It will not work in production builds.
Promise<boolean>A promise which fulfils when the task is triggered.
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.
Event subscriptions
Adds a listener that is called when the background executor expires. On iOS, tasks can run for minutes, but the system can interrupt the process at any time. This listener is called when the system decides to stop the background tasks and should be used to clean up resources or save state. When the expiry handler is called, the main task runner is rescheduled automatically.
{
remove: () => void
}An object with a remove method to unsubscribe the listener.
Types
Enums
Return value for background tasks.