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

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

启用后台模式能力后,将以下内容添加到您的应用程序的 AppDelegate.swift 中:
在文件顶部,import Capacitor 下方添加:
import CapacitorBackgroundRunner
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// ....
BackgroundRunnerPlugin.registerBackgroundTask()
BackgroundRunnerPlugin.handleApplicationDidFinishLaunching(launchOptions: launchOptions)
// ....
return true
}
为了让后台运行器处理远程通知,添加以下内容:
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(Privacy - Location Always Usage Description)NSLocationWhenInUseUsageDescription(Privacy - Location When In Use Usage Description)
阅读 iOS 指南 中的 配置 Info.plist 部分,了解更多关于在 Xcode 中设置 iOS 权限的信息。
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 权限的信息。
关于后台运行器
在构建复杂应用程序的过程中,有时需要在应用程序不在前台时执行工作。标准 Capacitor 应用程序的挑战在于,当这些后台事件发生时,WebView 不可用,需要您编写原生代码来处理这些事件。这就是后台运 行器插件的用武之地。
后台运行器使编写 JavaScript 代码来处理原生后台事件变得容易。您只需要创建运行器 JavaScript 文件并 定义您的配置,然后后台运行器插件将自动配置和调度一个原生后台任务,该任务将根据您的配置和平台规则执行。无需修改您的 UI 代码。
使用后台运行器
后台运行器包含一个无头 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 + ' 你好';
updatedUser.lastName = updatedUser.lastName + ' 世界';
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 的异步调用可能无法解析。
有关使用后台运行器的更多实际示例,请查看 后台运行器测试应用。
配置后台运行器
加载时,后台运行器将自动注册一个后台任务,该任务将在您的应用程序进入后台时被调度和执行。
| 属性 | 类型 | 描述 | 始于 |
|---|---|---|---|
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
后台运行器不在浏览器或 WebView 中执行您的 JavaScript 代码,因此您可能习惯的典型 Web API 可能不可用。这包括 DOM API 以及与应用程序 DOM 交互的能力。
以下是后台运行器中提供的可用 Web API 列表:
- console
- 仅
info、log、warn、error和debug可用
- 仅
- TextDecoder
- 仅
decode可用
- 仅
- TextEncoder
- 仅
encode可用
- 仅
- addEventListener
- 不支持事件监听器选项和
useCapture
- 不支持事件监听器选项和
- setTimeout
- setInterval
- clearTimeout
- clearInterval
- crypto
- fetch
- 尚不支持 Request 对象
- 在选项对象中仅支持
method、headers和body
除了标准的 Web API,后台运行器还支持许多 自定义 Capacitor API,这些自定义 API 公开了相关的移动设备功能。
运行器生命周期
目前,运行器设计用于在应用程序处于后台时执行周期性工作,或在应用程序处于前台时在与 UI 分离的线程中执行异步工作。因此,运行器不是长期存活的。运行器中的事件调用之间不维护状态。每次调用 dispatchEvent() 都会创建一个新的上下文来加载和执行您的运行器代码,一旦调用 resolve() 或 reject(),该上下文就会被销毁。
Android 电池优化
一些 Android 厂商提供内置的电池优化设置,这些设置超出了标准 Android 的功能。其中一些优化必须由您的最终用户禁用,以便您的后台任务正常工作。
访问 Don't kill my app! 了解更多关于受影响的制造商以及您的用户调整设置所需步骤的信息。
后台任务的限制
在移动操作系统上,无法运行持久且始终运行的后台服务。由于iOS和Android为减少电池消耗和数据使用而施加了限制,后台任务受到各种限制,在设计和实现后台任务时,你必须牢记这些限制。