插上充电器才干活,HarmonyOS 7 后台批量整理调度策略
·
用户睡觉时应用在干什么
我们的截图整理工具有一个“全量深度整理”功能:把过去半年的截图全部重新跑一遍 OCR、人脸检测和智能分类。这个操作极度消耗算力,如果用户一边刷抖音,应用在后台偷偷跑模型,手机早就烫得降频了。
解决这种后台重任务的唯一正解是 WorkScheduler。它的逻辑是“我不规定你几点跑,我只规定条件,系统觉得条件合适了,自然会叫醒你”。最典型的条件就是:设备在充电、连着 Wi-Fi、电量充足。

条件设置的合理阈值
不要在条件里堆叠太多诉求。比如你设置了“必须连着特定 WiFi 且充电且电量>90%”,系统可能要等到海枯石烂才会触发一次。
typescript
import { workScheduler } from '@kit.BackgroundTasksKit';
const workInfo: workScheduler.WorkInfo = {
workId: 1001,
bundleName: 'com.example.screenshot.organizer',
abilityName: 'BatchProcessWorker',
// 要求网络可用
networkType: workScheduler.NetworkType.NETWORK_TYPE_WIFI,
// 要求正在充电
isCharging: true,
// 要求电量至少 60%
batteryLevel: 60
};
try {
workScheduler.startWork(workInfo);
console.info('后台整理任务注册成功');
} catch (error) {
console.error(`注册失败: ${error.code}`);
}
startWork 只是注册,不代表立即执行。系统甚至可能三天都不触发一次,这完全取决于用户的使用习惯。
常见错误是以为后台任务可以像定时器一样精准。官方有一个执行窗口的概念,onWorkStart 被拉起后,你大约只有两分钟的连续执行时间。超过两分钟,EnterpriseAdminExtensionAbility 会被系统直接干掉。

断点续传与游标记录
既然只有两分钟,我们就不能指望一次性把半年的截图全部处理完。必须在代码里做好切片和断点。
typescript
import { workScheduler } from '@kit.BackgroundTasksKit';
export default class BatchProcessWorker extends workScheduler.WorkSchedulerExtensionAbility {
onWorkStart(work: workScheduler.WorkInfo): void {
// 1. 从 Preferences 或数据库读取上次处理到的图片游标
let cursor = getLastProcessedCursor();
// 2. 在下一个 Tick 里开启异步处理
this.processInBatches(cursor);
}
async processInBatches(startCursor: number) {
const batchSize = 20;
let current = startCursor;
while (Date.now() - this.startTime < 100 * 1000) { // 留 20 秒容错
const images = await db.getImages(current, batchSize);
if (images.length === 0) break; // 处理完了
await processImages(images);
current += images.length;
saveCursor(current); // 持续落盘游标
}
}
}
saveCursor 是这段代码的生命线。每次处理完一批就存一次,下次 onWorkStart 被拉起时接着干。如果没有这个游标,每次系统唤醒都从头开始处理,对于几万张截图的库,你永远也整理不完。
更多推荐
所有评论(0)