短时任务(ArkTS)速记 & 开发小抄
一句话理解: 应用快要被挂起前,向系统“打个招呼”,再多要一点点后台运行时间,把收尾工作做完。
1. 为什么需要短时任务?
正常情况下:
- 应用退到后台 → 一段时间后进程会被挂起 → 无法继续跑代码。
但有些场景需要:
- 退后台前保存状态 / 发一条消息 / 同步一点数据,时间不长,但又不能被中途砍掉。 → 这时候就用 短时任务(suspend delay) ,让应用在后台还能「多活一会儿」。
典型用途:
- 保存草稿、保存关卡进度
- 发送关键埋点 / 日志 / 消息
- 做一个很短的小收尾逻辑
2. 使用限制 & 配额规则
2.1 申请时机
不在这两个时机申请 = 必失败
-
只能在:
- 应用处于前台时
- 或者
onBackground回调里 调用requestSuspendDelay()。
2.2 数量限制
- 同一时刻,一个应用最多有 3 个短时任务 在跑。
2.3 配额机制(重点记忆)
-
系统会给每个应用一个「短时任务额度」,由系统根据状态和用户习惯动态调整,大致规则:
- 单日(24 小时)配额:默认 10 分钟
- 单次最长:3 分钟
- 低电量时单次:默认 1 分钟
-
计时规则(只在后台计时、同一时间段不重复算):
- 只有当应用在后台,短时任务才消耗配额。
- 同一应用在同一时间段内有多个短时任务 → 只算一次时间(不叠加)。
图里的意思就是: 前台不计时,后台有短时任务就开始计,当 A 结束但 B 还在→ 继续计时。
2.4 超时 & 主动取消
-
当短时任务快超时时:
-
系统会回调你在
requestSuspendDelay里传的callback。 -
你应该在回调里:
- 做一点简单的清理 / 标记
- 然后调用
cancelSuspendDelay()取消短时任务。
-
-
如果超时你还不取消:
-
系统会对你的应用「下手」:
- 进程挂起,严重时直接终止进程。
-
-
强烈推荐: 业务自己结束时,也主动
cancelSuspendDelay,节省配额。
3. 相关 API 一览(backgroundTaskManager)
import { backgroundTaskManager } from '@kit.BackgroundTasksKit';
import { BusinessError } from '@kit.BasicServicesKit';
3.1 申请短时任务
function requestSuspendDelay() {
let myReason = 'test requestSuspendDelay'; // 申请原因(日志可见)
try {
let delayInfo = backgroundTaskManager.requestSuspendDelay(myReason, () => {
// ⬇️ 短时任务即将超时时会回调这里
console.info('suspend delay task will timeout');
try {
backgroundTaskManager.cancelSuspendDelay(id);
} catch (error) {
console.error(`cancelSuspendDelay failed. code: ${(error as BusinessError).code}, message: ${(error as BusinessError).message}`);
}
});
id = delayInfo.requestId; // 本次短时任务 ID(后续查询 / 取消用)
delayTime = delayInfo.actualDelayTime; // 实际给你的延长时间 ms
} catch (error) {
console.error(`requestSuspendDelay failed. code: ${(error as BusinessError).code}, message: ${(error as BusinessError).message}`);
}
}
-
返回的
DelaySuspendInfo里有:requestId:短时任务编号actualDelayTime:这次系统实际给了你多少时间(可能比上限少)
3.2 查询剩余时间
async function getRemainingDelayTime() {
backgroundTaskManager.getRemainingDelayTime(id)
.then((res: number) => {
console.info('Succeeded in getting remaining delay time.', res); // 单位 ms
// 根据 res 判断要不要执行下一个小任务
})
.catch((err: BusinessError) => {
console.error(`Failed to get remaining delay time. Code: ${err.code}, message: ${err.message}`);
});
}
用法建议: 比如你有两个小任务 A、B,做完 A 后看下剩余时间够不够做 B,不够就只做 A,避免被系统硬停。
3.3 取消短时任务
function cancelSuspendDelay() {
try {
backgroundTaskManager.cancelSuspendDelay(id);
} catch (error) {
console.error(`cancelSuspendDelay failed. code: ${(error as BusinessError).code}, message: ${(error as BusinessError).message}`);
}
}
使用习惯:
- 业务自然结束时主动 cancel
- 系统回调里(即将超时)也要 cancel 双保险,保护配额 & 避免被系统惩罚。
4. 实战流程(可以脑补时序)
-
前台 /
onBackground()里:- 调用
requestSuspendDelay()→ 拿到id。
- 调用
-
正常执行你的后台收尾逻辑(例如保存 / 发消息)。
-
(可选)根据
getRemainingDelayTime(id)判断要不要继续做其它任务。 -
业务完成:
- 主动
cancelSuspendDelay(id)。
- 主动
-
如果忘了取消,快超时时系统会调用你传的
callback:- 在 callback 里做最后清理 + 再次
cancelSuspendDelay(id)。
- 在 callback 里做最后清理 + 再次