长时任务不是永久保活,你申请的类别根本不对
给一个文件同步功能加了长时任务,以为退后台之后进程就不会被冻结,同步能一直跑。结果用户切出去几分钟,任务照样停了。查文档才发现两个问题叠在一起:申请的 backgroundModes 和实际业务不匹配,文件下载/上传应该用 dataTransfer,不是随便选一个看起来“通用”的类别;而且长时任务本身也不承诺进程永久保活,系统在资源紧张或策略收紧时照样会限制。

长时任务、短时任务、WorkScheduler 是三件不同的事
长时任务解决的是“退后台后进程不被挂起冻结”,典型场景是后台音乐、导航、运动记录、后台录音,必须由 UIAbility 在前台申请,配置 backgroundModes 和 KEEP_BACKGROUND_RUNNING 权限,并且通知栏必须有一条持续通知。短时任务解决的是“即将被挂起前争取几分钟收尾”,单次最多 3 分钟,全天总配额有限,适合保存草稿、提交状态、小文件上传,不适合长期后台。WorkScheduler 解决的是“等条件合适时让系统唤醒跑一次”,进程可以完全销毁,触发时间不保证精确,适合日志上传、缓存清理、周期性同步,不适合实时持续业务。
typescript
import { backgroundTaskManager } from '@kit.BackgroundTasksKit';
async function startDataTransfer(context: common.UIAbilityContext): Promise<void> {
const wantAgentInfo: wantAgent.WantAgentInfo = {
wants: [{ bundleName: context.abilityInfo.bundleName, abilityName: 'EntryAbility' }],
actionType: wantAgent.OperationType.START_ABILITY,
};
const wantAgentObj = await wantAgent.getWantAgent(wantAgentInfo);
await backgroundTaskManager.startBackgroundRunning(
context, backgroundTaskManager.BackgroundMode.DATA_TRANSFER, wantAgentObj
);
}
BackgroundMode.DATA_TRANSFER 必须和实际业务对齐。文件下载/上传用其他模式申请,审核会打回,运行时也可能被系统判定为不合规。

WorkScheduler 最短周期是 2 小时,而且重启后任务会丢
如果你想让一个同步任务“每 30 分钟跑一次”,WorkScheduler 做不到。周期性任务的最小间隔是 2 小时,实际触发还会受到应用活跃分组、电量、网络条件的共同影响。startWork 返回 0 只代表“注册到了调度队列”,不代表“马上会执行”。另一个容易忽略的点:WorkScheduler 的任务是内存级的,设备重启后丢失,需要自己把任务配置持久化,在启动时重新注册。
后台保活的核心判断是“你的任务到底需要什么级别的存活”。实时持续、用户可感知的,走长时任务,类别必须匹配业务;短暂收尾、几分钟内能结束的,走短时任务,别拿它当长期保活用;非实时、条件驱动的,走 WorkScheduler,接受 2 小时的最小周期和触发不确定性。别指望长时任务做永久保活,系统不会给任何应用那个承诺。
更多推荐

所有评论(0)