@capacitor/background-runner
Background Runner 提供了一个基于事件的独立 JavaScript 环境,用于在 Web 视图之外执行您的 JavaScript 代码。
安装
npm install @capacitor/background-runner@latest-7
npx cap sync
Background Runner 支持多种设备 API,这些 API 在使用前需要获得用户权限。
iOS
在 iOS 上,您必须启用后台模式能力。

启用后,您至少需要开启 Background fetch 和 Background processing 模式,以便能够注册和调度您的后台任务。
如果您需要使用地理位置或推送通知功能,请分别启用 Location updates 或 Remote notifications。

您还需要在 Info.plist 文件中添加以下条目:
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>com.example.background.task</string>
</array>
有关在 Xcode 中设置 iOS 权限的更多信息,请阅读 iOS 指南 中的 配置 Info.plist。
请确保您在插件配置的 label 字段中使用与 BGTaskSchedulerPermittedIdentifiers 相同的标识符(例如 "com.example.background.task")。
启用后台模式能力后,将以下代码添加到您应用的 AppDelegate.swift 中:
在文件顶部,import Capacitor 下方添加:
import CapacitorBackgroundRunner
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// ....
BackgroundRunnerPlugin.registerBackgroundTask()
BackgroundRunnerPlugin.handleApplicationDidFinishLaunching(launchOptions: launchOptions)
// ....
return true
}
为了让 Background Runner 处理远程通知,添加以下代码:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
// ....
BackgroundRunnerPlugin.dispatchEvent(event: "remoteNotification", eventArgs: userInfo) { result in
switch result {
case .success:
completionHandler(.newData)
case .failure:
completionHandler(.failed)
}
}
}
地理位置
Apple 要求必须在 Info.plist 中为位置信息指定隐私描述:
NSLocationAlwaysUsageDescription(隐私 - 始终使用位置描述)NSLocationWhenInUseUsageDescription(隐私 - 使用期间使用位置描述)
Android
将以下行插入 android/app/build.gradle:
...
repositories {
flatDir{
dirs '../capacitor-cordova-android-plugins/src/main/libs', 'libs'
+ dirs '../../node_modules/@capacitor/background-runner/android/src/main/libs', 'libs'
}
}
...
如果您是从 1.0.5 版本升级现有 Android 项目,请确保删除 android/src/main/libs 中的 android-js-engine-release.aar。
地理位置
此 API 要求将以下权限添加到您的 AndroidManifest.xml:
<!-- 地理位置 API -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:name="android.hardware.location.gps" />
前两个权限请求位置数据,包括精确和粗略位置,最后一行是可选的,但如果您的应用需要 GPS 才能运行则是必需的。您可以省略它,但请注意,这可能意味着您的应用会安装在缺乏 GPS 硬件的设备上。
本地通知
Android 13 需要权限检查才能发送通知。您需要相应地调用 checkPermissions() 和 requestPermissions()。
在 Android 12 及更早版本上,它不会显示提示,只会返回已授予权限。
从 Android 12 开始,除非将以下权限添加到您的 AndroidManifest.xml,否则定时通知将不会是精确的:
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
请注意,即使存在此权限,用户仍然可以从应用设置中禁用精确通知。
有关设置 Android 权限的更多信息,请阅读 Android 指南 中的 设置权限。
关于 Background Runner
在构建复杂应用的过程中,有时需要在应用不在前台时执行任务。标准 Capacitor 应用面临的挑战是,当这些后台事件发生时,Web 视图不可用,这要求您编写原生代码来处理这些事件。这就是 Background Runner 插件的用武之地。
Background Runner 让编写 JavaScript 代码处理原生后台事件变得简单。您只需要创建运行器 JavaScript 文件并定义您的配置,Background Runner 插件就会自动配置和调度一个原生后台 任务,该任务将根据您的配置和平台规则执行。无需修改您的 UI 代码。
使用 Background Runner
Background Runner 包含一个无界面的 JavaScript 环境,它调用您在 capacitor.config.ts 文件中指定的 JavaScript 文件中的事件处理程序。如果运行器在您的运行器文件中找到与传入事件对应的事件处理程序,它将执行该事件处理程序,然后在调用 resolve() 或 reject() 后关闭(或者如果操作系统强制终止您的进程)。#### 示例运行器 JS 文件
addEventListener('myCustomEvent', (resolve, reject, args) => {
console.log('在此处执行系统更新操作');
resolve();
});
addEventListener('myCustomEventWithReturnData', (resolve, reject, args) => {
try {
console.log('接收到的数据: ' + JSON.stringify(args.user));
const updatedUser = args.user;
updatedUser.firstName = updatedUser.firstName + ' HELLO';
updatedUser.lastName = updatedUser.lastName + ' WORLD';
resolve(updatedUser);
} catch (err) {
reject(err);
}
});
addEventListener('remoteNotification', (resolve, reject, args) => {
try {
console.log('收到静默推送通知');
CapacitorNotifications.schedule([
{
id: 100,
title: '企业级后台运行器',
body: '收到静默推送通知',
},
]);
resolve();
} catch (err) {
reject();
}
});
在运行器调用的每个事件处理程序中,必须调用 resolve() 或 reject()。如果不这样做,当应用处于后台时调用事件,可能导致运行器被操作系统终止。如果应用在前台,对 dispatchEvent 的异步调用可能无法正常解析。
要查看更多使用 Background Runner 的实际示例,请访问 Background Runner 测试应用 。
配置 Background Runner
加载时,Background Runner 会自动注册一个后台任务,该任务将在应用进入后台后调度执行一次。
| 属性 | 类型 | 描述 | 自版本 |
|---|---|---|---|
label | string | 运行器名称,用于日志记录。 | 1.0.0 |
src | string | 运行器 JavaScript 文件路径,相对于应用包。 | 1.0.0 |
event | string | 当操作系统执行后台任务时调用的事件名称。 | 1.0.0 |
repeat | boolean | 后台任务是否应根据 interval 设置的间隔重复执行。 | 1.0.0 |
interval | number | 应用进入后台后,后台任务开始执行的分钟数。如果 repeat 为 true,这也指定了每次执行之间的分钟间隔。 | 1.0.0 |
autoStart | boolean | 应用加载时自动注册并调度后台任务。 | 1.0.0 |
示例
在 capacitor.config.json 中:
{
"plugins": {
"BackgroundRunner": {
"label": "com.example.background.task",
"src": "runners/background.js",
"event": "myCustomEvent",
"repeat": true,
"interval": 15,
"autoStart": true
}
}
}
在 capacitor.config.ts 中:
/// <reference types="@capacitor/background-runner" />
import { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
plugins: {
BackgroundRunner: {
label: "com.example.background.task",
src: "runners/background.js",
event: "myCustomEvent",
repeat: true,
interval: 15,
autoStart: true,
},
},
};
export default config;
JavaScript API
Background Runner 不在浏览器或 WebView 中执行 JavaScript 代码,因此您可能依赖的标准 Web API 可能不可用。这包括 DOM API 以及与应用程序 DOM 交互的能力。
以下是 Background Runner 中提供的可用 Web API 列表:
- console
- 仅支持
info、log、warn、error和debug
- 仅支持
- TextDecoder
- 仅支持
decode方法
- 仅支持
- TextEncoder
- 仅支持
encode方法
- 仅支持
- addEventListener
- 不支持事件监听器选项和
useCapture参数
- 不支持事件监听器选项和
- setTimeout
- setInterval
- clearTimeout
- clearInterval
- crypto
- fetch
- 尚不支持 Request 对象
- 在 options 对象中仅支持
method、headers和body
除了标准的 Web API,Background Runner 还支持一系列自定义 Capacitor API,这些 API 提供了相关的移动设备功能。
运行器生命周期
目前,运行器设计用于在应用处于后台时执行周期性的工作,或在应用处于前台时在与 UI 线程分离的线程中执行异步工作。因此,运行器不是长期存活的。运行器在不同事件调用之间不保持状态。每次调用 dispatchEvent() 都会创建一个 新的上下文来加载和执行运行器代码,一旦调用 resolve() 或 reject(),该上下文就会被销毁。
Android 电池优化
一些 Android 厂商提供了超出原生 Android 的电池优化设置。为了让后台任务正常工作,最终用户可能需要禁用其中的某些优化。
访问 Don't kill my app! 获取受影响厂商的更多信息以及用户调整设置所需的步骤。
后台任务的限制
在移动操作系统上无法运行持久、始终运行的后台服务。由于 iOS 和 Android 为减少电池和数据消耗而施加的限制,后台任务受到各种约束,在设计和实现后台任务时必须牢记这些限制。### iOS
- 每次任务调用的运行时间大约为 30 秒,之后必须调用
completed(),否则任务将被终止。 - 虽然你可以设置一个时间间隔来定义应用进入后台后任务何时运行,或者它应该运行的频率,但这并不能得到保证。iOS 会根据应用的使用频率等因素,最终决定任务何时以及以何种频率运行。
- 后台任务无法在模拟器中执行。
Android
- 你的任务最多有 10 分钟的时间来执行工作,但为了保持任务的跨平 台兼容性,你应该将工作时间限制在最多 30 秒。
- 重复性后台任务的最小间隔至少为 15 分钟。与 iOS 类似,你请求的任何间隔时间都可能无法精确满足——实际的执行时间会受到操作系统电池优化和其他启发式算法的影响。
API
checkPermissions()
checkPermissions() => any
检查各种 Capacitor 设备 API 的权限。
返回值: any
自: 1.0.0
requestPermissions(...)
requestPermissions(options: RequestPermissionOptions) => any
请求显示本地通知的权限。
| 参数 | 类型 |
|---|---|
options | |
返回值: any
自: 1.0.0
dispatchEvent(...)
dispatchEvent<T = void>(options: DispatchEventOptions) => any
向配置的运行器(runner)分派事件。
| 参数 | 类型 |
|---|---|
options | |
返回值: any
自: 1.0.0
addListener('backgroundRunnerNotificationReceived', ...)
addListener(eventName: 'backgroundRunnerNotificationReceived', listenerFunc: (event: NotificationActionEvent) => void) => any
添加通知操作(notification actions)的监听器。
| 参数 | 类型 |
|---|---|
eventName | 'backgroundRunnerNotificationReceived' |
listenerFunc | |
返回值: any
自: 2.1.1
removeNotificationListeners()
removeNotificationListeners() => any
移除此插件的通知操作监听器。
返回值: any
自: 2.1.1
接口
PermissionStatus
| 属性 | 类型 |
|---|---|
geolocation | |
notifications | |
RequestPermissionOptions
| 属性 | 类型 |
|---|---|
apis | {} |
DispatchEventOptions
| 属性 | 类型 | 描述 | 自 |
|---|---|---|---|
label | string | 要向其分派事件(dispatch event)的运行器标签 | 1.0.0 |
event | string | 已注册的事件监听器的名称。 | 1.0.0 |
details | { [key: string]: any; } |
NotificationActionEvent
| 属性 | 类型 |
|---|---|
actionTypeId | string |
notificationId | number |
PluginListenerHandle
| 属性 | 类型 |
|---|---|
remove | () => any |
类型别名
PermissionState
'prompt' | 'prompt-with-rationale' | 'granted' | 'denied'
API
'geolocation' | 'notifications'
Capacitor API
接口
CapacitorDevice
获取设备信息,例如网络连接状态和电池状态。
| 属性 | 类型 | 描述 | 自 |
|---|---|---|---|
getBatteryStatus | | 获取设备的当前电池状态。 | 1.0.0 |
getNetworkStatus | | 获取设备的当前网络状态。 | 1.0.0 |
BatteryStatus
| 属性 | 类型 |
|---|---|
batteryLevel | number |
isCharging | boolean |
NetworkStatus
| 属性 | 类型 |
|---|---|
connected | boolean |
connectionType | string |
CapacitorKV
一个简单的字符串键/值存储,在 iOS 上由 UserDefaults 支持,在 Android 上由 Shared Preferences 支持。
| 属性 | 类型 | 描述 | 自 |
|---|---|---|---|
set | (key: string, value: string) => void | 使用给定的键设置一个字符串值。 | 1.0.0 |
get | (key: string) => { value: string; } | 获取给定键对应的字符串值。 | 1.0.0 |
remove | (key: string) => void | 移除给定键对应的值。 | 1.0.0 |
#### CapacitorNotifications
发送基础本地通知。
| 属性 | 类型 | 描述 | 始于版本 |
|---|---|---|---|
schedule | (options: {}) => void | 安排一个本地通知 | 1.0.0 |
setBadge | | 设置应用角标计数 | 2.0.0 |
clearBadge | () => void | 清除应用角标计数 | 2.0.0 |
| --------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- |
id | number | 通知标识符。在 Android 上为 32 位整数,因此取值范围应在 -2147483648 到 2147483647 之间(含边界值)。 | 1.0.0 |
title | string | 通知标题。 | 1.0.0 |
body | string | 通知正文,显示在标题下方。 | 1.0.0 |
scheduleAt | Date | 发送此通知的日期时间。 | 1.0.0 |
sound | string | 显示此通知时要播放的音频文件名(需包含文件扩展名)。在 iOS 中,文件应位于应用包内;在 Android 中,文件应位于 res/raw 目录下。推荐使用 .wav 格式,因为 iOS 和 Android 均支持该格式。此属性仅适用于 iOS 和 Android < 26 版本。对于 Android 26+,请使用配置了所需音效的 channelId。如果未找到音效文件(例如空字符串或错误文件名),将使用默认系统通知音效。若不提供此属性,Android 将播放默认音效,iOS 则不播放任何声音。 | 1.0.0 |
actionTypeId | string | 与此通知关联的操作类型标识符。 | 1.0.0 |
threadIdentifier | string | 用于对多个通知进行分组。设置 UNMutableNotificationContent 的 threadIdentifier 属性。仅适用于 iOS。 | 1.0.0 |
summaryArgument | string | 此通知添加到分类摘要格式字符串中的内容。设置 UNMutableNotificationContent 的 summaryArgument 属性。仅适用于 iOS。 | 1.0.0 |
group | string | 用于对多个通知进行分组。在 NotificationCompat.Builder 上调用 setGroup() 方法并传入该值。仅适用于 Android。 | 1.0.0 |
extra | any | 设置存储在此通知中的额外数据。 | 1.0.0 |
ongoing | boolean | 如果设为 true,通知将无法被滑动清除。会调用 NotificationCompat.Builder 的 setOngoing() 方法并传入该值。仅适用于 Android 平台。 | 1.0.0 |
autoCancel | boolean | 如果设为 true,用户点击通知时会自动取消该通知。会调用 NotificationCompat.Builder 的 setAutoCancel() 方法并传入该值。仅适用于 Android 平台。 | 1.0.0 |
largeBody | string | 设置用于大文本通知样式的多行文本块。 | 1.0.0 |
summaryText | string | 用于设置收件箱和大文本通知样式中的摘要文本详情。仅适用于 Android 平台。 | 1.0.0 |
smallIcon | string | 设置自定义状态栏图标。如果设置此选项,将覆盖 Capacitor 配置中的 smallIcon 选项。图标应放置在应用的 res/drawable 文件夹中。此选项的值应为可绘制资源 ID,即不带扩展名的文件名。仅适用于 Android 平台。 | 1.0.0 |
largeIcon | string | 为通知设置大图标。图标应放置在应用的 res/drawable 文件夹中。此选项的值应为可绘制资源 ID,即不带扩展名的文件名。仅适用于 Android 平台。 | 1.0.0 |
channelId | string | 指定通知应投递到的渠道。如果指定名称的渠道不存在,则通知不会触发。如果未提供,将使用默认渠道。会调用 NotificationCompat.Builder 的 setChannelId() 方法并传入该值。仅适用于 Android 26+ 版本。 | 1.0.0 |
| 属性 | 类型 | 描述 | 引入版本 |
|---|---|---|---|
count | number | 设置应用徽章上显示的数字。 | 2.0.0 |
notificationTitle | string | 必需 与徽章计数通知关联的标题。仅适用于 Android。 | 2.0.0 |
notificationSubtitle | string | 与徽章计数通知关联的副标题。仅适用于 Android。 | 2.0.0 |
CapacitorGeolocation
获取设备位置信息。
| 属性 | 类型 | 描述 | 引入版本 |
|---|---|---|---|
getCurrentPosition | | 获取设备最后已知的位置 | 1.0.0 |
GetCurrentPositionResult
| 属性 | 类型 | 描述 | 引入版本 |
|---|---|---|---|
latitude | number | 纬度,单位为十进制度 | 1.0.0 |
longitude | number | 经度,单位为十进制度 | 1.0.0 |
accuracy | number | 纬度和经度坐标的精度级别,单位为米 | 1.0.0 |
altitude | number | null | 用户所在的海拔高度(如果可用) | 1.0.0 |
altitudeAccuracy | number | null | 海拔坐标的精度级别,单位为米(如果可用)。在所有 iOS 版本和 Android 8.0+ 上可用。 | 1.0.0 |
speed | number | null | 用户的移动速度(如果可用) | 1.0.0 |
heading | number | null | 用户面对的方向(如果可用) | 1.0.0 |
CapacitorWatch
与已配对此应用的手表进行交互。
sendMessage、transferUserInfo 和 updateApplicationContext 是通向 WCSession 委托方法的原始路由,但在 CapacitorWatch 手表应用中目前没有实际效果。 如果开发一个原生手表应用作为 Capacitor 应用的配套应用,则可以使用它们。
| 属性 | 类型 | 描述 |
|---|---|---|
sendMessage | (options: []) => void | 使用 sendMessage() WCSession 委托方法向手表发送消息。这对 CapacitorWatch 手表应用没有效果。 |
transferUserInfo | (options: []) => void | 使用 transferUserInfo() WCSession 委托方法向手表发送信息。这对 CapacitorWatch 手表应用没有效果。 |
updateApplicationContext | (options: []) => void | 使用 updateApplicationContext() WCSession 委托方法更新手表上的应用上下文。这对 CapacitorWatch 手表应用没有效果。 |
isReachable | boolean | 检查配套手表是否可达 |
updateWatchUI | (options: { watchUI: string; }) => void | 用此处指定的内容替换手表上当前的用户界面。 |
updateWatchData | (options: { data: { [key: string]: string; }; }) => void | 更新手表用于在文本和按钮字段中显示变量的数据 |
CapacitorApp
| 属性 | 类型 |
|---|---|
getState | |
getInfo | |
AppState
| 属性 | 类型 | 描述 | 引入版本 |
|---|---|---|---|
isActive | boolean | 应用是否处于活动状态。 | 1.0.0 |
AppInfo
| 属性 | 类型 | 描述 | 引入版本 |
|---|---|---|---|
name | string | 应用的名称。 | 1.0.0 |
id | string | 应用的标识符。在 iOS 上是 Bundle Identifier。在 Android 上是 Application ID。 | 1.0.0 |
build | string | 构建版本。在 iOS 上是 CFBundleVersion。在 Android 上是 versionCode。 | 1.0.0 |
version | string | 应用版本。在 iOS 上是 CFBundleShortVersionString。在 Android 上是 package 的 versionName。 | 1.0.0 |