HarmonyOS:延迟任务(ArkTS)

一、概述

1.1 功能介绍

应用退至后台后,需要执行实时性要求不高的任务,例如有网络时不定期主动获取邮件等,可以使用延迟任务。当应用满足设定的触发条件(包括网络类型、充电类型、存储状态、电池状态、定时状态等)时,将任务添加到执行队列,系统会根据内存、功耗、设备温度、用户使用习惯等统一调度拉起应用。

1.2 运行原理

图1 延迟任务实现原理

应用调用延迟任务接口添加、删除、查询延迟任务,延迟任务管理模块会根据任务设置的条件(通过WorkInfo参数设置,包括网络类型、充电类型、存储状态等)和系统状态(包括内存、功耗、设备温度、用户使用习惯等)统一决策调度时机。

当满足调度条件或调度结束时,系统会回调应用WorkSchedulerExtensionAbility中 onWorkStart () 或 onWorkStop () 的方法,同时会为应用单独创建一个Extension扩展进程用以承载WorkSchedulerExtensionAbility ,并给WorkSchedulerExtensionAbility一定的活动周期,开发者可以在对应回调方法中实现自己的任务逻辑。

1.3 约束与限制

  • 数量限制:一个应用同一时刻最多申请10个延迟任务。
  • 执行频率限制:系统会根据应用的活跃分组,对延迟任务做分级管控,限制延迟任务调度的执行频率。

表1 应用活跃程度分组

应用活跃分组 延迟任务执行频率
活跃分组 最小间隔2小时
经常使用分组 最小间隔4小时
常用分组 最小间隔24小时
极少使用分组 最小间隔48小时
受限使用分组 禁止
从未使用分组 禁止
  • 超时:WorkSchedulerExtensionAbility单次回调最长运行2分钟。如果超时不取消,系统会终止对应的Extension进程。
  • 调度延迟:系统会根据内存、功耗、设备温度、用户使用习惯等统一调度,如当系统内存资源不足或温度达到一定挡位时,系统将延迟调度该任务。
  • WorkSchedulerExtensionAbility接口调用限制:为实现对WorkSchedulerExtensionAbility能力的管控,在WorkSchedulerExtensionAbility中限制以下接口的调用: @ohos.resourceschedule.backgroundTaskManager (后台任务管理) @ohos.backgroundTaskManager (后台任务管理) @ohos.multimedia.camera (相机管理) @ohos.multimedia.audio (音频管理) @ohos.multimedia.media (媒体服务)

二、接口说明

表2 延迟任务主要接口

以下是延迟任务开发使用的相关接口

接口名 接口描述
startWork(work: WorkInfo): void; 申请延迟任务
stopWork(work: WorkInfo, needCancel?: boolean): void; 取消延迟任务
getWorkStatus(workId: number, callback: AsyncCallback<WorkInfo>): void; 获取延迟任务状态(Callback形式)
getWorkStatus(workId: number): Promise; 获取延迟任务状态(Promise形式)
obtainAllWorks(callback: AsyncCallback<Array<WorkInfo>>): void; 获取所有延迟任务(Callback形式)
obtainAllWorks(): Promise<Array<WorkInfo>>; 获取所有延迟任务(Promise形式)
stopAndClearWorks(): void; 停止并清除任务
isLastWorkTimeOut(workId: number, callback: AsyncCallback): void; 获取上次任务是否超时(针对RepeatWork,Callback形式)
isLastWorkTimeOut(workId: number): Promise; 获取上次任务是否超时(针对RepeatWork,Promise形式)

表3 WorkInfo参数

名称 类型 只读 可选 说明
workId number 延迟任务ID。
bundleName string 延迟任务所在应用的包名。
abilityName string 包内ability名称。
networkType NetworkType 网络类型。
isCharging boolean 是否充电。 - true表示充电触发延迟任务回调。 - false表示不充电触发延迟任务回调。
chargerType ChargingType 充电类型。
batteryLevel number 电量。
batteryStatus BatteryStatus 电池状态。
storageRequest StorageRequest 存储状态。
isRepeat boolean 是否循环任务。 - true表示循环任务。 - false表示非循环任务。
repeatCycleTime number 循环间隔,单位为毫秒。
repeatCount number 循环次数。
isPersisted boolean 注册的延迟任务是否可保存在系统中。 - true表示可保存,即系统重启后,任务可恢复。 - false表示不可保存。
isDeepIdle boolean 是否要求设备进入空闲状态。 - true表示需要。 - false表示不需要。
idleWaitTime number 空闲等待时间,单位为毫秒。
parameters [key: string]: number | string | boolean 携带参数信息。

WorkInfo参数用于设置延迟任务的触发条件,参数设置时需遵循以下规则:

  • workId、bundleName、abilityName为必填项,bundleName需为本应用包名。
  • 携带参数信息仅支持number、string、boolean三种类型。
  • 至少设置一个满足的条件,包括网络类型、充电类型、存储状态、电池状态、定时状态等。
  • 对于重复任务,任务执行间隔至少2小时。设置重复任务时间间隔时,须同时设置是否循环或循环次数中的一个。
    表4 延迟任务回调接口

以下是延迟任务回调开发使用的相关接口,更多接口及使用方式请见延迟任务调度回调文档。

接口名 接口描述
onWorkStart(work: workScheduler.WorkInfo): void 延迟调度任务开始的回调
onWorkStop(work: workScheduler.WorkInfo): void 延迟调度任务结束的回调

三、开发步骤

延迟任务调度开发步骤分为两步:实现延迟任务调度扩展能力、实现延迟任务调度。

  1. 延迟任务调度扩展能力:实现WorkSchedulerExtensionAbility开始和结束的回调接口。
  2. 延迟任务调度:调用延迟任务接口,实现延迟任务申请、取消等功能。

3.1 实现延迟任务回调扩展能力

  1. 新建工程目录。 在工程entry Module对应的ets目录(./entry/src/main/ets)下,新建目录及ArkTS文件,例如新建一个目录并命名为WorkSchedulerExtension。在WorkSchedulerExtension目录下,新建一个ArkTS文件并命名为WorkSchedulerExtension.ets,用以实现延迟任务回调接口。
  2. 导入模块。
bash 复制代码
import { WorkSchedulerExtensionAbility, workScheduler } from '@kit.BackgroundTasksKit';
  1. 实现WorkSchedulerExtension生命周期接口。
bash 复制代码
export default class MyWorkSchedulerExtensionAbility extends WorkSchedulerExtensionAbility {
  // 延迟任务开始回调
  onWorkStart(workInfo: workScheduler.WorkInfo) {
    console.info(`onWorkStart, workInfo = ${JSON.stringify(workInfo)}`);
    // 打印 parameters中的参数,如:参数key1
    // console.info(`work info parameters: ${JSON.parse(workInfo.parameters?.toString()).key1}`)
  }

  // 延迟任务结束回调。当延迟任务2分钟超时或应用调用stopWork接口取消任务时,触发该回调。
  onWorkStop(workInfo: workScheduler.WorkInfo) {
    console.info(`onWorkStop, workInfo is ${JSON.stringify(workInfo)}`);
  }
}
  1. 在module.json5配置文件中注册WorkSchedulerExtensionAbility,并设置如下标签:
  • type标签设置为"workScheduler"。
  • srcEntry标签设置为当前ExtensionAbility组件所对应的代码路径。
bash 复制代码
{
  "module": {
      "extensionAbilities": [
        {
          "name": "MyWorkSchedulerExtensionAbility",
          "srcEntry": "./ets/WorkSchedulerExtension/WorkSchedulerExtension.ets",
          "type": "workScheduler"
        }
      ]
  }
}

3.2 实现延迟任务调度

示例效果图

示例完整代码 WorkSchedulerExtension.ets

bash 复制代码
import { workScheduler, WorkSchedulerExtensionAbility } from '@kit.BackgroundTasksKit';
import { BusinessError } from '@kit.BasicServicesKit';

const TAG = "MyWorkSchedulerExtensionAbility"
export default class MyWorkSchedulerExtensionAbility extends WorkSchedulerExtensionAbility {
  // 延迟任务开始回调
  onWorkStart(workInfo: workScheduler.WorkInfo) {
    console.info(`${TAG} onWorkStart 回调, workInfo = ${JSON.stringify(workInfo)}`);
    // 打印 parameters中的参数,如:参数key1
    // console.info(`work info parameters: ${JSON.parse(workInfo.parameters?.toString()).key1}`)
  }
  // 延迟任务结束回调。当延迟任务2分钟超时或应用调用stopWork接口取消任务时,触发该回调。
  onWorkStop(workInfo: workScheduler.WorkInfo) {
    console.info(`${TAG} onWorkStop 回调, workInfo is ${JSON.stringify(workInfo)}`);
  }

  /**
   * 申请延迟任务。
   */
  startWorkScheduler() {
    // 创建workinfo
    const workInfo: workScheduler.WorkInfo = {
      workId: 1,
      networkType: workScheduler.NetworkType.NETWORK_TYPE_WIFI,
      bundleName: 'com.learn.learnharmonyos',
      abilityName: 'MyWorkSchedulerExtensionAbility'
    }

    try {
      workScheduler.startWork(workInfo);
      console.info(`${TAG} 执行 startWorkScheduler startWork success`);
    } catch (error) {
      console.error(`TAG} 执行 startWorkScheduler startWork failed. code is ${(error as BusinessError).code} message is ${(error as BusinessError).message}`);
    }
  }

  /**
   * 取消延迟任务。
   */
  stopWorkScheduler() {
    // 创建workinfo
    const workInfo: workScheduler.WorkInfo = {
      workId: 1,
      networkType: workScheduler.NetworkType.NETWORK_TYPE_WIFI,
      bundleName: 'com.example.application',
      abilityName: 'MyWorkSchedulerExtensionAbility'
    }

    try {
      workScheduler.stopWork(workInfo);
      console.info(`stopWork success`);
    } catch (error) {
      console.error(`stopWork failed. code is ${(error as BusinessError).code} message is ${(error as BusinessError).message}`);
    }
  }
}

TestBackgroundTasksKit4.ets

bash 复制代码
import MyWorkSchedulerExtensionAbility from '../../workSchedulerExtension/WorkSchedulerExtension'
@Entry
@Component
struct TestBackgroundTasksKit4 {
  myWorkSchedulerExtensionAbility: MyWorkSchedulerExtensionAbility = new MyWorkSchedulerExtensionAbility()

  build() {
    Column({space: 20}) {
      Button('申请延迟任务')
        .fontColor(Color.Black)
        .fontSize(20)
        .margin({top: 10})
        .onClick(() => {
          this.myWorkSchedulerExtensionAbility.startWorkScheduler()
        })
      Button('取消延迟任务')
        .fontColor(Color.Black)
        .margin({top: 10})
        .fontSize(20)
        .onClick(() => {
          this.myWorkSchedulerExtensionAbility.stopWorkScheduler()
        })
    }
    .height('100%')
    .width('100%')
  }
}

3.3 延迟任务调度功能验证

确认延迟任务WorkSchedulerExtensionAbility回调方法onWorkStart、onWorkStop实现是否正确、是否可以成功回调

延迟任务申请成功之后,需要等到条件满足后才可以执行延迟任务回调,为了快速验证延迟任务回调功能是否正确,可以通过以下hidumper命令手动触发延迟任务执行回调。

bash 复制代码
$ hidumper -s 1904 -a '-t com.example.application MyWorkSchedulerExtensionAbility'

-------------------------------[ability]-------------------------------


----------------------------------WorkSchedule----------------------------------

提醒 需要先配置hidumper系统环境变量

相关推荐
ChinaDragon13 小时前
HarmonyOS:通过组件导航设置自定义区域
harmonyos
人工智能知识库14 小时前
华为HCIP-HarmonyOS Application Developer题库 H14-231 (26年最新带解析)
华为·harmonyos·hcip-harmonyos·h14-231
搬砖的kk14 小时前
鸿蒙 PC 版 DevEco Studio 使用 OHPM 下载三方库教程
华为·harmonyos
游戏技术分享1 天前
【鸿蒙游戏技术分享 第75期】AGC后台批量导入商品失败,提示“参数错误”
游戏·华为·harmonyos
No Silver Bullet1 天前
HarmonyOS NEXT开发进阶(十七):WebView 拉起 H5 页面
华为·harmonyos
liuhaikang1 天前
【鸿蒙HarmonyOS Next App实战开发】口语小搭档——应用技术实践
harmonyos
liuhaikang1 天前
鸿蒙VR视频播放库——md360player
音视频·vr·harmonyos
飞露1 天前
鸿蒙Preview预览文件失败原因
华为·harmonyos
夏小鱼的blog1 天前
【HarmonyOS应用开发入门】第五期:状态管理V2入门 - 1
harmonyos·状态管理
小雨青年1 天前
鸿蒙 HarmonyOS 6 | ArkUI (04):数据展示 List 列表容器 LazyForEach 懒加载机制
华为·list·harmonyos