设备返回主界面、锁屏、应用切换等操作会使应用退至后台。应用退至后台后,如果继续活动,可能会造成设备耗电快、用户界面卡顿等现象。为了降低设备耗电速度、保障用户使用流畅度,系统会对退至后台的应用进行管控,包括进程挂起(Suspend,即系统不再为应用进程分配 CPU 时间片,同时对应的公共事件等不再发给应用进程)和进程终止(Terminate)。
- 应用退至后台一小段时间(由系统定义),应用进程会被挂起;
- 资源不足时,系统会终止部分应用进程(即回收该进程的所有资源);
同时,为了保障后台音乐播放、日历提醒等功能的正常使用,系统提供了规范内受约束的后台任务,扩展应用在后台运行时间。
提示:对于鸿蒙系统中运行的所有进程,系统会给予一定的资源配额约束,包括进程在连续一段时间内内存的使用、CPU 使用占比,以及 24 小时磁盘写的 IO 量,均有对应的配额上限。
超过配额上限时,如果进程处于前台,系统会生成 warning 日志;如果进程处于后台,系统会终止该进程
后台任务类型
应用退至后台后如果有继续运行的需求,可申请使用如下几种受系统约束的后台任务:
- 短时任务:适用于实时性要求高、耗时不长的任务,例如状态持久化保存。
- 长时任务:适用于长时间运行在后台、用户可感知的任务,例如后台播放音乐、导航、设备连接等,使用长时任务避免应用进程被挂起。
- 延迟任务:对于实时性要求不高、可延迟执行的任务,系统提供了延迟任务,即满足条件的应用退至后台后被放入执行队列,系统会根据内存、功耗等统一调度;例如:2 小时后自动到邮件服务器收取邮件。
- 代理提醒:代理提醒是指应用退后台或进程终止后,系统会代理应用做相应的提醒。适用于定时提醒类业务,例如通知用户定时抢票应用等。
说明:
1、系统仅支持规范内受约束的后台任务。应用退至后台后,若未使用规范内的后台任务或选择的后台任务类型不正确,对应的应用进程会被挂起或终止。
2、应用申请了规范内的后台任务,仅会提升应用进程被回收的优先级。当系统资源严重不足时,即使应用进程申请了规范内的后台任务,系统仍会终止部分进程,用以保障系统稳定性。
短时任务
应用退至后台一小段时间后,会被系统挂起,无法执行对应的任务。如果应用在后台仍需要执行耗时不长的任务,如状态保存等,可以通过申请短时任务,扩展应用在后台的运行时间。
短时任务使用限制:
- 申请时机:应用需要在前台或 onBackground 回调内,申请短时任务,否则会申请失败。
- 数量限制:一个应用同一时刻最多申请执行 3 个 短时任务。
- 配额机制:一个应用会有一定的短时任务配额(根据系统状态和用户习惯调整),单日(24 小时内)配额默认为 10 分钟,单次配额最大为 3 分钟,低电量时单次配额默认为 1 分钟,配额消耗完后不允许再申请短时任务。
- 配额计算:仅当应用在后台时,对应用下的短时任务计时;同一个应用下的同一个时间段的短时任务,不重复计时。
- 超时:短时任务即将超时时,系统会回调应用,应用需要取消短时任务。如果超时不取消,系统会终止对应的应用进程。
主要接口
下面的 API 都在 backgroundTaskManager 名称空间下
接口名 | 描述 |
---|---|
requestSuspendDelay(reason: string, callback: Callback<void>): DelaySuspendInfo |
申请短时任务 |
getRemainingDelayTime(requestId: number): Promise<number> |
获取对应短时任务的剩余时间 |
cancelSuspendDelay(requestId: number): void |
取消短时任务 |
例子
ts
import backgroundTaskManager from '@ohos.resourceschedule.backgroundTaskManager'
@Entry
@Component
struct Index {
requestId: number = 0 //申请编号,即应用申请延迟挂起这个操作的编号,即后台短时任务编号
timerId: number = 0 //周期性定时器编号
shortTimeBackgroundTask() {
let count = 0
this.timerId = setInterval(() => {
count++
console.log('--' + count + ' 后台任务正在执行', Date.now())
}, 1000)
}
build() {
Column({ space: 10 }) {
Text('后台任务之一:短时任务')
.fontSize(30)
Button('1.申请执行短时任务A(申请当前应用延迟一会儿再挂起)').onClick(async _ => {
try {
//请求系统延迟挂起当前应用,我想执行一些短时任务
let info = backgroundTaskManager.requestSuspendDelay('申请状态持久化短时任务', () => {
console.log('--短时任务时间配额即将到期!请立即执行一些最后的清理操作!')
clearInterval(this.timerId) //清理当前页面正在占用的资源
backgroundTaskManager.cancelSuspendDelay(this.requestId) //取消挂起延迟,即取消后台任务
})
//上述挂起延迟申请成功的话,下面的代码就是在"挂起延迟"这段时间内执行的短时后台任务:
//获得短时任务编号
this.requestId = info.requestId
//查看当前短时任务剩余的时间配额(以ms为单位)
let time = await backgroundTaskManager.getRemainingDelayTime(this.requestId)
if (time >= 60000) {
console.log('--剩余时间配额足够,开始执行后台任务')
this.shortTimeBackgroundTask()
} else {
console.log('--剩余的时间配额不足以执行目标任务')
}
} catch (err) {
console.log('--申请挂起延迟用以执行短时后台任务失败:', JSON.stringify(err))
}
})
Button('取消短时任务').onClick(_ => {
backgroundTaskManager.cancelSuspendDelay(this.requestId)
})
}
.height('100%')
.width('100%')
.padding(10)
}
}
长时任务
应用退至后台后,在后台需要长时间运行用户可感知的任务,如播放音乐、导航等。为防止应用进程被挂起,导致对应功能异常,可以申请长时任务,使应用在后台长时间运行。
长时任务分为如下类型
参数名 | 描述 | 配置项 | 场景举例 |
---|---|---|---|
DATA_TRANSFER | 数据传输 | dataTransfer | 后台下载大文件,如浏览器后台下载等 |
AUDIO_PLAYBACK | 音视频播放 | audioPlayback | 音乐类应用在后台播放音乐 |
AUDIO_RECORDING | 录制 | audioRecording | 录音机在后台录音 |
LOCATION | 定位导航 | location | 导航类应用后台导航 |
BLUETOOTH_INTERACTION | 蓝牙相关 | bluetoothInteraction | 通过蓝牙传输分享的文件 |
MULTI_DEVICE_CONNECTION | 多设备互联 | multiDeviceConnection | 分布式业务连接(如手机与平板、电视等互联) |
TASK_KEEPING | 计算任务(仅对 2IN1 开放) | taskKeeping | 杀毒软件在后台进行病毒扫描等任务 |
约束与限制
1、申请限制:Stage 模型中,长时任务仅支持 UIAbility 申请;FA 模型中,长时任务仅支持 ServiceAbility 申请。
2、数量限制:一个 UIAbility 同一时刻仅支持申请一个长时 任务,即在一个长时任务结束后才可能继续申请。如果一个应用同时需要申请多个长时任务,需要创建多个 UIAbility;一个应用的一个 UIAbility 申请长时任务后,整个应用下的所有进程均不会被挂起。
3、运行限制:在手机产品上,系统会进行长时任务校验,例如:
- 场景 ①:若应用申请了长时任务,但未真正执行申请类型的长时任务或申请类型的任务已结束,系统会对应用进行管控。例如系统检测到应用申请了 AUDIO_PLAYBACK(音视频播放),但实际未播放音乐,长时任务会被取消。
- 场景 ②:若应用没有申请对应的长时任务类型,但执行了相关类型的长时任务,系统会对应用进行管控。例如系统检测到应用只申请了 AUDIO_PLAYBACK(音视频播放),但实际上除了播放音乐,还在进行录制(对应 AUDIO_RECORDING 类型),系统会对应用进行管控。
- 场景 ③:若运行长时任务的进程后台负载持续高于所申请类型的典型负载,系统会对应用进行管控。
主要接口
接口名 | 描述 |
---|---|
startBackgroundRunning(context: Context, bgMode: BackgroundMode, wantAgent: WantAgent): Promise<void> |
申请长时任务 |
stopBackgroundRunning(context: Context): Promise<void> |
取消长时任务 |
说明:
1、长时任务需申请系统级权限 ohos.permission.KEEP_BACKGROUND_RUNNING 才能使用
2、必须在 module.json5 文件中为 UIAbility 配置相应的长时任务类型 backgroundModes
3、申请长时任务成功后,系统会在通知栏显示相关通知,点击通知可以拉起任务对应的窗口
示例
后台定位服务
当前模块配置 module.json5
json
{
"module": {
"abilities": [
{
"name": "EntryAbility",
//申请当前UIAbility可以哪些类型的"后台长时任务"
"backgroundModes": ["location"]
}
//一个UIAbility某个时刻只能执行一个后台长时任务,但是可以先后执行多个长时任务
],
"requestPermissions": [
//当前应用申请数据和功能的访问权限
//系统授予级权限 ------ 只需要声明name即可
{
"name": "ohos.permission.KEEP_BACKGROUND_RUNNING"
//保持应用在后台持续运行
},
//用户授予级权限 ------ 必须声明name/reason/usedScene三个属性
{
"name": "ohos.permission.APPROXIMATELY_LOCATION",
//模糊定位
"reason": "$string:app_name", // 这里用户会看到的申请权限原因,我这里乱写的
"usedScene": {
"abilities": ["EntryAbility"],
"when": "always"
}
},
{
"name": "ohos.permission.LOCATION",
//精确定位
"reason": "$string:app_name",
//当前应用需要向用户解释使用该权限的原因
"usedScene": {
//权限在何种场景下被使用
"abilities": ["EntryAbility"],
//哪些Ability/窗口中需要使用该权限
"when": "always"
//何时使用该权限 inuse:当前应用在前台运行时需要使用 always:总是需要该权限,即使应用没在运行
}
}
]
}
}
ts
import { abilityAccessCtrl, bundleManager, Permissions, wantAgent } from '@kit.AbilityKit'
import { geoLocationManager } from '@kit.LocationKit'
import { backgroundTaskManager } from '@kit.BackgroundTasksKit'
@Entry
@Component
struct Index {
//页面显式时,先弹出"申请定位权限"授权窗口
async onPageShow() {
//① 声明需要用户授权的权限列表
let list: Permissions[] = ['ohos.permission.APPROXIMATELY_LOCATION', 'ohos.permission.LOCATION']
//② 获得当前应用的"访问令牌"
let flags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION //需要获得整个应用的信息,而不是模块的/应用组件的
let bundleInfo = await bundleManager.getBundleInfoForSelf(flags) //得到当前资源包信息
let tokenId = bundleInfo.appInfo.accessTokenId //当前应用的当前分身在当前用户使用场景下,系统分配的令牌编号
let atManager = abilityAccessCtrl.createAtManager() //At: Access Token,访问令牌,即当前应用的授权列表
let grantStatus0 = await atManager.checkAccessToken(tokenId, list[0])
let grantStatus1 = await atManager.checkAccessToken(tokenId, list[1])
//③ 从访问令牌中查询,用户是否授予过定位权限
if (grantStatus0 == -1 && grantStatus1 == -1) { //0表示已经通过授权了 -1表尚未尚未授权/之前拒绝授权了
//④ 如果尚未授权过,则弹出申请授权对话框
let result = await atManager.requestPermissionsFromUser(getContext(), list)
if (result.authResults[0] == 0) {
console.log('1.模糊定位权限已经从用户处申请到')
} else {
console.log('2.用户拒绝授予模糊定位权限')
}
if (result.authResults[1] == 0) {
console.log('3.精确定位权限已经从用户处申请到')
} else {
console.log('4.用户拒绝授予精确定位权限')
}
}
}
longTimeBackgroundTask() {
try {
if (!geoLocationManager.isLocationEnabled()) {
console.log('--当前系统没有打开定位开关!')
return
}
let count = 0
geoLocationManager.on('locationChange', {}, (loc) => {
count++
console.log('--当前设备位置改变了:', count, JSON.stringify(loc))
})
} catch (err) {
console.log('--持续性定位失败!', JSON.stringify(err))
}
}
build() {
Column({ space: 10 }) {
Text('后台任务之二:长时任务')
.fontSize(30)
Button('1.申请执行后台长时任务:持续性定位').onClick(async _ => {
geoLocationManager.getCurrentLocation({}, (err, loc) => {
if (!err) console.log('单次定位成功:', loc);
});
try {
let wa = await wantAgent.getWantAgent({
//创建一个want代理,用于给系统通知被点击后跳转到哪个UIAbility
wants: [{ bundleName: 'com.example.quanguokefei', abilityName: 'EntryAbility' }],
requestCode: Date.now(), // 使用者定义的一个私有值,这里为了避免重复导致任务无法开启
actionType: wantAgent.OperationType.START_ABILITY, //必需属性,指定用户点击通知消息作何处理
})
console.log('--Want代理创建完成')
//开启一个长时后台任务
backgroundTaskManager.startBackgroundRunning(
getContext(), //参数1:上下文
backgroundTaskManager.BackgroundMode.LOCATION, //参数2:后台任务类型
wa //参数3:Want代理对象
//()=>{ }, //参数4:长时任务的内容
).then(() => {
console.log('--长时任务已经开启,开始执行持续性定位操作...')
this.longTimeBackgroundTask()
})
} catch (err) {
console.log('--长时任务开启失败!', JSON.stringify(err))
}
})
Button('2.关闭后台长时任务').onClick(async _ => {
await backgroundTaskManager.stopBackgroundRunning(getContext()) //关闭当前后台任务,后续就可以继续开启其它后台任务了
// await backgroundTaskManager.stopBackgroundRunning(getContext(), ()=>{})
console.log('--停止后台长时任务成功')
geoLocationManager.off('locationChange')
console.log('--手工关闭持续性定位成功')
})
}
.height('100%')
.width('100%')
.padding(10)
}
}
延迟任务
应用退至后台后,需要执行实时性要求不高的任务,例如有网络时不定期主动获取邮件等,可以使用延迟任务。当应用满足设定条件(包括网络类型、充电类型、存储状态、电池状态、定时状态等)时,将任务添加到执行队列,系统会根据内存、功耗、设备温度、用户使用习惯等统一调度拉起应用
约束与限制
1、数量限制:一个应用同一时刻最多申请 10 个 延迟任务。
2、执行频率限制:系统会根据应用的活跃分组,对延迟任务做分级管控,限制延迟任务调度的执行频率。
应用活跃分组 | 延迟任务最小执行间隔 | 备注 |
---|---|---|
活跃分组 | 2 小时 | 高频使用应用 |
经常使用分组 | 4 小时 | 中频使用应用 |
常用使用分组 | 24 小时 | 低频使用应用 |
极少使用分组 | 48 小时 | 极少唤醒应用 |
受限使用分组 | 禁止 | 系统限制后台任务 |
从未使用分组 | 禁止 | 完全冻结后台行为 |
3、超时:WorkSchedulerExtensionAbility 单次回调最长运行 2 分钟。如果超时不取消,系统会终止对应的 Extension 进程。
4、调度延迟:系统会根据内存、功耗、设备温度、用户使用习惯等统一调度,如当系统内存资源不足或温度达到一定挡位时,系统将延迟调度该任务。
5、WorkSchedulerExtensionAbility 接口调用限制:为实现对 WorkSchedulerExtensionAbility 能力的管控,在其中限制以下接口的调用:后台任务管理/相机管理/音频管理/媒体服务
主要接口
接口名 | 接口描述 |
---|---|
startWork(work: WorkInfo): void |
申请延迟任务 |
stopWork(work: WorkInfo, needCancel?: boolean): void |
取消延迟任务 |
getWorkStatus(workId: number, callback: AsyncCallback<WorkInfo>): void |
获取延迟任务状态(Callback 形式) |
getWorkStatus(workId: number): Promise<WorkInfo> |
获取延迟任务状态(Promise 形式) |
obtainAllWorks(callback: AsyncCallback<Array<WorkInfo>>): void |
获取所有延迟任务(Callback 形式) |
obtainAllWorks(): Promise<Array<WorkInfo>> |
获取所有延迟任务(Promise 形式) |
stopAndClearWorks(): void |
停止并清除任务 |
isLastWorkTimeOut(workId: number, callback: AsyncCallback<boolean>): void |
获取上次任务是否超时(针对 RepeatWork,Callback 形式) |
isLastWorkTimeOut(workId: number): Promise<boolean> |
获取上次任务是否超时(针对 RepeatWork,Promise 形式) |
示例
第一步:使用 DevEco Studio 辅助创建 WorkSchedulerExtensionAbility
比如我创建的名字是 EntryWorkSchedulerExtAbility
ts
import {
workScheduler,
WorkSchedulerExtensionAbility,
} from "@kit.BackgroundTasksKit";
//扩展的延迟任务应用组件,会由系统提供的"任务调度器"来启动,运行在专有的ExtensionAbility进程中
export default class WorkSchedulerExtension extends WorkSchedulerExtensionAbility {
timerId: number = 0;
onWorkStart(workInfo: workScheduler.WorkInfo) {
console.log(
"--WorkSchedulerExtension.onWorkStart:延迟任务开始执行了...",
JSON.stringify(workInfo)
);
//TODO: 发起HTTP请求,获取邮件服务器上当前用户最新的邮件...
let count = 0;
this.timerId = setInterval(() => {
count++;
console.log("--" + count + " 延迟任务执行中:", Date.now());
}, 1000);
}
onWorkStop(workInfo: workScheduler.WorkInfo) {
console.log(
"--WorkSchedulerExtension.onWorkStop:延迟任务终止执行了",
JSON.stringify(workInfo)
);
clearInterval(this.timerId);
console.log("--已经手工清理了延迟任务相关的资源对象");
}
}
第二步:申请开启延迟任务 和 取消延迟任务
ts
import { workScheduler } from '@kit.BackgroundTasksKit'
@Entry
@Component
struct Index {
build() {
Column({ space: 10 }) {
Text('后台任务之三:延迟任务')
.fontSize(30)
Button('1.申请注册一个延迟任务').onClick(_ => {
const workId: number = Math.floor(1000 + Math.random() * 9000)
const work: workScheduler.WorkInfo = {
workId, //必需,延迟任务编号 ------ 注意:同编号的任务再次添加,会抛出错误:9700005
bundleName: 'com.example.quanguokefei', //必需,延迟任务所在的应用
abilityName: 'EntryWorkSchedulerExtAbility', //必需,延迟任务所在的ExtensionAbility
//必需属性:当前延迟任务在何种条件下可以获得执行:
// isCharging: true, //只有处于充电状态下才能执行
// chargerType: workScheduler.ChargingType.CHARGING_PLUGGED_USB, //只有在指定的充电设备类型时才执行
batteryStatus: workScheduler.BatteryStatus.BATTERY_STATUS_OKAY, //只有电池状态处于OK(>20%)时才执行
// networkType: workScheduler.NetworkType.NETWORK_TYPE_WIFI, //只有网络进入指定的状态类型时才执行
// storageRequest: workScheduler.StorageRequest.STORAGE_LEVEL_OKAY, //只有外存剩余存储空间达到指定状态才执行
// repeatCycleTime: 1000*60*60*2 //间隔多久执行一次当前任务
}
try {
workScheduler.startWork(work) //向系统注册一个延迟任务
console.log('--UIAbility/主进程中注册了一个延迟任务,编号为:' + workId)
} catch (err) {
console.log('--UIAbility/主进程中注册延迟任务失败', JSON.stringify(err))
}
})
}
.height('100%')
.width('100%')
.padding(10)
}
}
效果是自动输出 2 分钟后因为超时被系统自动杀死
代理提醒
应用退到后台或进程终止后,仍然有一些提醒用户的定时类任务,例如购物类应用抢购提醒等,为满足此类功能场景,系统提供了代理提醒(reminderAgentManager)的能力。当应用退至后台或进程终止后,系统会代理应用做相应的提醒。当前支持的提醒类型包括:倒计时、日历和闹钟。
- 倒计时类(Timer):基于倒计时的提醒功能,例如:2 小时后提醒吃药。
- 日历类(Calendar):基于日历的提醒功能,例如:12 月 12 日凌晨提醒抢票。
- 闹钟类(Alarm):基于时钟的提醒功能,例如:08:00 叫我起床。
约束与限制
1、个数限制:一个三方应用支持最多 30 个有效提醒(有效即发布成功),一个系统应用支持最多 2000 个有效提醒,整个系统最多支持 12000 个有效提醒。
2、跳转限制:点击提醒通知后跳转的应用必须是申请代理提醒的本应用。
3、管控限制:为了防止代理提醒被用于滥用于广告、营销类提醒,影响用户体验,代理增加了管控机制。管控后可通过日历 Calendar Kit 替代代理提醒,实现相应的提醒功能。
所以,这小节的示例代码能跑,但是被限制死了。提醒不是不可以发,得有些实力和背景
{"data":1700002,"code":1700002,"message":"The number of reminders exceeds the limit."}
主要接口
接口名 | 描述 |
---|---|
publishReminder(reminderReq: ReminderRequest): Promise<number> |
发布一个定时提醒类通知 |
cancelReminder(reminderId: number): Promise<void> |
取消一个指定的提醒类通知 |
getValidReminders(): Promise<Array<ReminderRequest>> |
获取当前应用设置的所有有效的提醒 |
cancelAllReminders(): Promise<void> |
取消当前应用设置的所有提醒 |
addNotificationSlot(slot: NotificationSlot): Promise<void> |
注册一个提醒类需要使用的通知通道(NotificationSlot) |
removeNotificationSlot(slotType: notification.SlotType): Promise<void> |
删除指定的通知通道(NotificationSlot) |
说明:
1、代理提醒需申请系统级权限 ohos.permission. PUBLISH_AGENT_REMINDER 才能使用
2、应用需要获取用户授权才能发送通知。在通知发布前调用
requestEnableNotification()
方法
json
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.PUBLISH_AGENT_REMINDER" //允许当前应用委托鸿蒙系统发起一个通知(称为代理提醒)
}
]
}
}
示例
ts
import { notificationManager } from '@kit.NotificationKit'
import { common } from '@kit.AbilityKit'
import { reminderAgentManager } from '@kit.BackgroundTasksKit'
import { JSON } from '@kit.ArkTS'
@Entry
@Component
struct Index {
//页面即将显示时,弹出提醒用户允许当前应用发起通知或代理通知 ------ 类似于用户级权限授权,但代码不一样
async onPageShow() {
if (!notificationManager.isNotificationEnabledSync()) {
console.log('--当前应用 尚未 向用户申请过"发起通知"弹窗')
let ctx = getContext() as common.UIAbilityContext
await notificationManager.requestEnableNotification(ctx)
console.log('--当前应用 成功 获得了用户的通知弹窗许可')
}else {
console.log('--当前应用 已经 向用户申请过"发起通知"弹窗,可能通过了,也可能是未通过')
}
}
build() {
Column({ space: 10 }) {
Text('后台任务之四:代理提醒')
.fontSize(30)
Button('1.申请发布一个代理提醒 ------ 倒计时类型').onClick(async _ => {
let req:reminderAgentManager.ReminderRequestTimer = {
reminderType: reminderAgentManager.ReminderType.REMINDER_TYPE_TIMER, //提醒类型:倒计时
triggerTimeInSeconds: 15, //多少秒钟后触发提醒
title: '温馨提示', //通知标题
content: '距离吃完饭已经2个小时,可以吃药了',
wantAgent: { //通知被点击后,拉起哪个UIAbility
pkgName: 'com.example.quanguokefei',
abilityName: 'EntryAbility'
}
}
try{
let rid = await reminderAgentManager.publishReminder(req)
console.log('--代理提醒发布完成,提醒的编号:', rid)
}catch(err){
console.log('--代理提醒发布失败', JSON.stringify(err))
//提醒:2024年10月28日之后,华为把应用可发布的代理提醒数量降为:0
}
})
Button('2.申请发布一个代理提醒 ------ 日历类型').onClick(async _ => {
let req:reminderAgentManager.ReminderRequestCalendar = {
reminderType: reminderAgentManager.ReminderType.REMINDER_TYPE_CALENDAR,
dateTime: {year:2025, month:12, day:12, hour:0, minute:0, second:0}, //必需是未来时间
title: '抢券提示',
content: '双12活动正式开始!!!',
wantAgent: {
pkgName: 'com.example.quanguokefei',
abilityName: 'EntryAbility'
},
}
try{
let rid = await reminderAgentManager.publishReminder(req)
console.log('--代理提醒发布完成,提醒的编号:', rid)
}catch(err){
console.log('--代理提醒发布失败', JSON.stringify(err))
//提醒:2024年10月28日之后,华为把应用可发布的代理提醒数量降为:0
}
})
Button('3.申请发布一个代理提醒 ------ 闹钟类型').onClick(async _ => {
let req:reminderAgentManager.ReminderRequestAlarm = {
reminderType: reminderAgentManager.ReminderType.REMINDER_TYPE_ALARM,
hour: 8,
minute: 0,
title: '温馨提示',
content: '早上8点了,该起床了',
wantAgent: {
pkgName: 'com.example.quanguokefei',
abilityName: 'EntryAbility'
},
}
try{
let rid = await reminderAgentManager.publishReminder(req)
console.log('--代理提醒发布完成,提醒的编号:', rid)
}catch(err){
console.log('--代理提醒发布失败', JSON.stringify(err))
//提醒:2024年10月28日之后,华为把应用可发布的代理提醒数量降为:0
}
})
}
.height('100%')
.width('100%')
.padding(10)
}
}
四大类后台任务对比
任务类型 | 数量限制 | 时长限制 | 任务内容 | 失效性 |
---|---|---|---|---|
短时任务 | 3 | 3min/单任务,10min/所有任务 | 无限制 | 立即执行 |
长时任务 | 1 | 无限制 | 七大类 | 立即执行 |
延迟任务 | 10 | m/单任务 | 只有四类不允许 | 未来条件满足时执行 |
代理提醒 | 30(需申请) | 仅能发提醒 | 仅能发提醒 | 未来条件满足时发提醒 |