news 2026/7/29 15:46:13

HarmonyOS应用开发实战:猫猫大作战-workScheduler 的使用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
HarmonyOS应用开发实战:猫猫大作战-workScheduler 的使用

前言

workScheduler(工作调度器)是 BackgroundTasksKit 中用于执行延迟/周期任务的能力。与startBackgroundRunning的持续运行不同,workScheduler 适合定时触发的短任务——如每日战绩上传、每周排行榜刷新、缓存清理等。

在「猫猫大作战」中,我们使用 workScheduler 实现每日定时上传战绩到云端,确保玩家的高分不会丢失,同时为未来的跨设备同步打下基础。

本文以「猫猫大作战」的定时战绩上传为锚点,讲解 workScheduler 的完整使用方法,包括WorkInfo 配置任务注册和取消WorkAbility 实现、以及约束条件设置

提示:本系列不讲 ArkTS 基础语法与环境搭建。本篇是阶段五第 163 篇。

一、workScheduler 基础

1.1 WorkInfo 配置

import { workScheduler } from '@kit.BackgroundTasksKit'; async function scheduleSync(context: Context): Promise<void> { const workInfo: workScheduler.WorkInfo = { workId: 1001, // 任务唯一 ID bundleName: 'com.maomaodazuozhan.game', // 包名 abilityName: 'SyncWorkAbility', // 执行任务的 Ability networkType: workScheduler.NetworkType.NETWORK_TYPE_WIFI, // 网络条件 isPersisted: true, // 重启后是否保留 repeatCycleTime: 24 * 60 * 60 * 1000, // 24 小时周期 }; try { await workScheduler.startWork(workInfo); console.info(`工作调度器已启动, workId: ${workInfo.workId}`); } catch (err) { console.error(`启动工作调度失败: ${err.message}`); } }

1.2 参数详解

参数类型必填说明
workIdnumber任务唯一标识,同一应用内不可重复
bundleNamestring应用包名,与应用配置一致
abilityNamestring执行后台任务的 Ability 类名
networkTypeNetworkType网络条件约束(WIFI/移动数据/不限)
isPersistedboolean设备重启后是否保留该任务
repeatCycleTimenumber循环周期(毫秒),不设为单次任务

提示:workId在同一个应用中必须唯一。建议用递增数字管理,或使用模块编号(如 1001=战绩上传、1002=排行榜刷新)。

二、WorkAbility 实现

2.1 创建 WorkAbility

// entry/src/main/ets/entryability/SyncWorkAbility.ets import { WorkSchedulerAbility, workScheduler } from '@kit.BackgroundTasksKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; export default class SyncWorkAbility extends WorkSchedulerAbility { private TAG = 'SyncWork'; private DOMAIN = 0xFF00; onWorkStart(workInfo: workScheduler.WorkInfo): void { hilog.info(this.DOMAIN, this.TAG, `后台任务启动: workId=${workInfo.workId}`); // 执行具体的后台任务 this.executeSyncTask().then(() => { hilog.info(this.DOMAIN, this.TAG, '后台任务执行完成'); }).catch((err) => { hilog.error(this.DOMAIN, this.TAG, `后台任务失败: ${err.message}`); }); } onWorkStop(workInfo: workScheduler.WorkInfo): void { hilog.info(this.DOMAIN, this.TAG, `后台任务停止: workId=${workInfo.workId}`); // 清理资源 } private async executeSyncTask(): Promise<void> { // 1. 读取本地战绩 const localData = await this.readLocalScores(); // 2. 上传到服务端 await this.uploadToCloud(localData); // 3. 清理过期缓存 await this.cleanCache(); } private async readLocalScores(): Promise<object> { // 从 RDB 或 Preferences 读取 return { /* ... */ }; } private async uploadToCloud(data: object): Promise<void> { // 调用网络 API 上传 hilog.info(this.DOMAIN, this.TAG, '上传战绩数据'); } private async cleanCache(): Promise<void> { // 清理 7 天前的缓存 hilog.info(this.DOMAIN, this.TAG, '清理缓存'); } }

2.2 module.json5 注册

{ module: { abilities: [ { name: 'SyncWorkAbility', srcEntry: './ets/entryability/SyncWorkAbility.ets', description: '$string:SyncWorkAbility_desc', icon: '$media:icon', label: '$string:SyncWorkAbility_label', type: 'workScheduler', exported: false, }, // ... ], } }

三、任务注册和管理

3.1 启动任务

export class SyncManager { // 每日战绩上传任务 static readonly SYNC_WORK_ID = 1001; // 每日排行榜刷新任务 static readonly RANK_WORK_ID = 1002; static async startDailySync(context: Context): Promise<void> { const workInfo: workScheduler.WorkInfo = { workId: this.SYNC_WORK_ID, bundleName: context.abilityInfo.bundleName, abilityName: 'SyncWorkAbility', networkType: workScheduler.NetworkType.NETWORK_TYPE_WIFI, isPersisted: true, repeatCycleTime: 24 * 60 * 60 * 1000, // 24h }; await workScheduler.startWork(workInfo); } static async startWeeklyRank(context: Context): Promise<void> { const workInfo: workScheduler.WorkInfo = { workId: this.RANK_WORK_ID, bundleName: context.abilityInfo.bundleName, abilityName: 'SyncWorkAbility', // 可复用相同的 Ability networkType: workScheduler.NetworkType.NETWORK_TYPE_WIFI, isPersisted: true, repeatCycleTime: 7 * 24 * 60 * 60 * 1000, // 7d }; await workScheduler.startWork(workInfo); } }

3.2 停止和查询任务

// 停止单个任务 async function stopSyncWork(context: Context): Promise<void> { try { await workScheduler.stopWork( context, SyncManager.SYNC_WORK_ID, true // true = 取消已等待但未执行的任务 ); console.info('定时同步已停止'); } catch (err) { console.error(`停止任务失败: ${err.message}`); } } // 查询任务状态 async function isWorkScheduled(workId: number): Promise<boolean> { try { const isScheduled = await workScheduler.isWorkScheduled(workId); console.info(`任务 ${workId}: ${isScheduled ? '已调度' : '未调度'}`); return isScheduled; } catch (err) { console.error(`查询任务状态失败: ${err.message}`); return false; } } // 获得所有已调度的任务 async function getAllScheduledWorks(context: Context): Promise<workScheduler.WorkInfo[]> { return await workScheduler.getAllScheduledWorks(context); }

3.3 约束条件

// 网络类型约束 enum NetworkType { NETWORK_TYPE_ANY, // 不限(WIFI 或移动数据) NETWORK_TYPE_MOBILE, // 仅移动数据 NETWORK_TYPE_WIFI, // 仅 WIFI(推荐) } // 其他约束(可通过 WorkInfo 设置) interface WorkInfo { // ... batteryLevel?: number; // 电量阈值(如 20% 以上才执行) isCharging?: boolean; // 是否仅充电时执行 storageLevel?: number; // 存储空间阈值 }
约束类型说明推荐值
networkTypeNetworkType网络条件WIFI(节省流量)
batteryLevelnumber最低电量百分比20
isChargingboolean是否需充电状态false
storageLevelnumber最低存储百分比10

四、性能与节电

4.1 任务执行限制

// workScheduler 任务的限制: // 1. 每次执行最长 2 分钟(超时自动停止) // 2. 单应用每日总执行时长有限制 // 3. 频率不宜过高(建议 ≥ 1 小时) // ✅ 推荐的周期任务间隔 const RECOMMENDED_INTERVALS = { HOURLY: 60 * 60 * 1000, // 1 小时 DAILY: 24 * 60 * 60 * 1000, // 24 小时(推荐) WEEKLY: 7 * 24 * 60 * 60 * 1000, // 7 天 };

4.2 省电策略

// 省电建议 // 1. WIFI 下执行(避免消耗移动数据) networkType: workScheduler.NetworkType.NETWORK_TYPE_WIFI, // 2. 仅充电时执行(适合大数据量同步) const workInfo: workScheduler.WorkInfo = { // ... isCharging: true, }; // 3. 合并多个任务到同一个 WorkAbility // 避免启动多个独立的后台任务,用一个 Ability 处理多个操作 export default class UnifiedWorkAbility extends WorkSchedulerAbility { onWorkStart(workInfo: workScheduler.WorkInfo): void { switch (workInfo.workId) { case 1001: this.syncScores(); break; case 1002: this.refreshRank(); break; case 1003: this.cleanCache(); break; } } }

五、常见场景

5.1 每日签到提醒

async function scheduleDailyReminder(context: Context): Promise<void> { const workInfo: workScheduler.WorkInfo = { workId: 2001, bundleName: context.abilityInfo.bundleName, abilityName: 'ReminderWorkAbility', isPersisted: true, repeatCycleTime: 24 * 60 * 60 * 1000, }; await workScheduler.startWork(workInfo); }

5.2 战绩云同步

// 游戏结束时触发一次同步(非周期任务) async function syncAfterGame(context: Context, score: number): Promise<void> { // 立即同步一次 const workInfo: workScheduler.WorkInfo = { workId: 3001, bundleName: context.abilityInfo.bundleName, abilityName: 'SyncWorkAbility', networkType: workScheduler.NetworkType.NETWORK_TYPE_WIFI, // 不设 repeatCycleTime → 单次任务 }; await workScheduler.startWork(workInfo); }

六、调试方法

// 使用 hdc 命令调试 workScheduler // hdc shell // hdc shell aa start -b com.maomaodazuozhan.game -a SyncWorkAbility // 查看已调度的任务 async function debugScheduledWorks(context: Context): Promise<void> { const works = await workScheduler.getAllScheduledWorks(context); console.info(`当前已调度 ${works.length} 个后台任务:`); for (const w of works) { console.info(` workId=${w.workId}, ability=${w.abilityName}, ` + `repeat=${w.repeatCycleTime}ms, persisted=${w.isPersisted}`); } }

七、常见问题

问题原因解决
任务未按时执行系统省电限制使用isPersisted=true并设置合理触发条件
WorkAbility 未启动module.json5 配置错误检查 ability 的 type 和 class 名称
workId 冲突重复 ID每个任务使用唯一 ID
后台任务执行超时任务超过 2 分钟拆分大任务、控制在 1 分钟内完成
设备重启后任务丢失isPersisted=false设置为 true

八、与其他后台方案对比

方案用途执行时长周期能力保活电量消耗
workScheduler延迟/周期任务≤ 2 分钟✅ 支持不保活
startBackgroundRunning持续后台任务长时间需保活
continuousTask短暂任务≤ 3 分钟不保活
前台 Service前台可见任务无限系统保活

九、最佳实践

  1. 优先使用 WIFInetworkType: NETWORK_TYPE_WIFI节省用户流量
  2. 周期合理:日常任务 24h 周期,避免小于 1 小时
  3. isPersisted=true:设备重启后自动恢复定时任务
  4. 统一 WorkAbility:用 switch 分发不同 workId,减少 Ability 数量
  5. 任务轻量化:单次执行控制在 30 秒内,避免超时
  6. 错误处理:任务内 try-catch,防止未捕获异常导致任务提前终止
  7. 电量感知:低电量或非充电时减少执行
// 最佳实践示例 async function scheduleBestPractice(context: Context): Promise<void> { const isCharging = await getBatteryStatus(); const networkType = isCharging ? workScheduler.NetworkType.NETWORK_TYPE_ANY : workScheduler.NetworkType.NETWORK_TYPE_WIFI; const workInfo: workScheduler.WorkInfo = { workId: 1001, bundleName: context.abilityInfo.bundleName, abilityName: 'SyncWorkAbility', networkType, isPersisted: true, repeatCycleTime: 24 * 60 * 60 * 1000, }; await workScheduler.startWork(workInfo); }

十、完整集成示例

@Entry @Component struct GameEntry { aboutToAppear() { this.initBackgroundTasks(); } async initBackgroundTasks() { const ctx = getContext() as common.UIAbilityContext; // 启动每日战绩同步 await SyncManager.startDailySync(ctx); // 启动每周排行榜刷新 await SyncManager.startWeeklyRank(ctx); console.info('后台任务初始化完成'); } // 游戏结束时触发一次同步 async onGameEnd(score: number) { await syncAfterGame(getContext() as common.UIAbilityContext, score); } }

总结

workScheduler 是 HarmonyOS 中执行延迟/周期后台任务的推荐方案,适合每日数据同步、缓存清理等定时操作。核心要点:WorkInfo 配置任务参数、 WorkSchedulerAbility 执行具体逻辑、isPersisted=true保重启持久化、 WIFI 约束省流量、 任务控制在 2 分钟内、 统一 WorkAbility 分发不同 workId

下一篇将深入 ReminderRequest——闹钟提醒的创建与管理。

如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!


相关资源:

  • workScheduler API 文档
  • BackgroundTasksKit 概述
  • WorkSchedulerAbility 参考
  • 后台任务开发指南
  • module.json5 配置
  • 省电优化最佳实践
  • 开源鸿蒙跨平台社区
  • HarmonyOS 开发者官方文档
  • 第 162 篇:bg-running
  • 第 164 篇:ReminderRequest
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/29 15:45:49

斐波那契数列:从递归到矩阵快速幂的C++实现与Python可视化

1. 项目概述&#xff1a;从数学之美到编程实践 最近在整理算法笔记时&#xff0c;我又把斐波那契数列&#xff08;Fibonacci Sequence&#xff09;拿出来琢磨了一遍。这个数列的魅力在于&#xff0c;它既是数学领域一个简洁优美的模型&#xff0c;又是计算机科学中检验算法思想…

作者头像 李华
网站建设 2026/7/29 15:45:17

基于CNN与MATLAB的GUI表情识别系统开发实践

1. 项目概述&#xff1a;基于CNN的GUI表情识别系统 这个项目实现了一个端到端的人脸表情识别系统&#xff0c;核心是用MATLAB搭建卷积神经网络(CNN)模型&#xff0c;通过GUI界面提供交互式操作体验。我在实际开发中发现&#xff0c;这种技术组合特别适合需要快速验证算法效果又…

作者头像 李华
网站建设 2026/7/29 15:45:11

5分钟彻底解决Windows软件依赖问题:VisualCppRedist AIO终极指南

5分钟彻底解决Windows软件依赖问题&#xff1a;VisualCppRedist AIO终极指南 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经遇到过这样的场景&#x…

作者头像 李华
网站建设 2026/7/29 15:43:39

脑筋急转弯API参数详解与接入最佳实践

适用场景 脑筋急转弯API提供随机返回一条本地题库内容&#xff08;题目 答案&#xff09;&#xff0c;适合以下典型场景&#xff1a; 聊天机器人趣味互动&#xff1a;在对话中随机插入一条脑筋急转弯题目&#xff0c;等待用户回答后自动揭晓答案&#xff0c;增加交互的轻松氛…

作者头像 李华
网站建设 2026/7/29 15:43:13

UG95与PIC32MZ实现物联网远程通信方案解析

1. 项目背景与核心组件解析"突破地理界限"这个标题背后&#xff0c;实际上是一个典型的物联网远程通信项目。UG95是一款支持LTE Cat 1bis的无线通信模块&#xff0c;而PIC32MZ2048EFH100则是Microchip推出的高性能32位MCU。两者的组合&#xff0c;能够为各类需要远程…

作者头像 李华
网站建设 2026/7/29 15:42:39

Flowise 本地部署完整指南

Flowise 本地部署完整指南 Flowise 可视化拖拽 LangChain 工作流&#xff0c;提供 3 种部署方案&#xff0c;优先推荐 Docker&#xff08;最省心、环境隔离&#xff09;&#xff1b;Windows/macOS/Linux 通用。 硬件最低&#xff1a;4G 内存&#xff1b;推荐 ≥8G 内存&#x…

作者头像 李华