1# 延迟任务 2 3## 概述 4 5### 功能介绍 6 7应用退至后台后,需要执行实时性要求不高的任务,例如有网络时不定期主动获取邮件等,可以使用延迟任务。当应用满足设定条件(包括网络类型、充电类型、存储状态、电池状态、定时状态等)时,将任务添加到执行队列,系统会根据内存、功耗、设备温度、用户使用习惯等统一调度拉起应用。 8 9### 运行原理 10 11**图1** 延迟任务实现原理 12 13 14应用调用延迟任务接口注册、删除、查询延迟任务,延迟任务管理模块会根据任务设置的条件(通过WorkInfo参数设置,包括网络类型、充电类型、存储状态等)和系统状态(包括内存、功耗、设备温度、用户使用习惯等)统一决策调度时机。 15 16当满足调度条件或调度结束时,系统会回调应用[WorkSchedulerExtensionAbility](../reference/apis/js-apis-WorkSchedulerExtensionAbility.md)中 onWorkStart() 或 onWorkStop() 的方法,同时会为应用单独创建一个Extension扩展进程用以承载[WorkSchedulerExtensionAbility](../reference/apis/js-apis-WorkSchedulerExtensionAbility.md),并给[WorkSchedulerExtensionAbility](../reference/apis/js-apis-WorkSchedulerExtensionAbility.md)一定的活动周期,开发者可以在对应回调方法中实现自己的任务逻辑。 17 18 19### 约束与限制 20 21- **数量限制**:一个应用同一时刻最多申请10个延迟任务。 22 23- **执行频率限制**:系统会根据[应用的活跃分组](../reference/apis/js-apis-resourceschedule-deviceUsageStatistics.md),对延迟任务做分级管控,限制延迟任务调度的执行频率。通过能效资源接口申请了WORK_SCHEDULER资源的应用,会被放在能效资源豁免分组中。 24 25 **表1** 应用活跃程度分组 26 | 应用活跃分组 | 延迟任务执行频率 | 27 | -------- | -------- | 28 | 活跃分组 | 最小间隔2小时 | 29 | 经常使用分组 | 最小间隔4小时 | 30 | 常用使用 | 最小间隔24小时 | 31 | 极少使用分组 | 最小间隔48小时 | 32 | 受限使用分组 | 禁止 | 33 | 从未使用分组 | 禁止 | 34 | 能效资源豁免分组 | 不受限制 | 35 36- **超时**:WorkSchedulerExtensionAbility单次回调最长运行2分钟。如果超时不取消,系统会终止对应的Extension进程。对于系统特权应用,可以通过能效资源接口申请WORK_SCHEDULER资源,扩展单次回调运行时长,扩展后在充电状态下为20分钟,非充电状态下为10分钟。 37 38- **调度延迟**:系统会根据内存、功耗、设备温度、用户使用习惯等统一调度,如当系统内存资源不足或温度达到一定挡位时,系统将延迟调度该任务。 39 40- **WorkSchedulerExtensionAbility接口调用限制**:为实现对WorkSchedulerExtensionAbility能力的管控,在WorkSchedulerExtensionAbility中限制以下接口的调用: 41 42 [@ohos.resourceschedule.backgroundTaskManager (后台任务管理)](../reference/apis/js-apis-resourceschedule-backgroundTaskManager.md) 43 44 [@ohos.backgroundTaskManager (后台任务管理)](../reference/apis/js-apis-backgroundTaskManager.md) 45 46 [@ohos.multimedia.camera (相机管理)](../reference/apis/js-apis-camera.md) 47 48 [@ohos.multimedia.audio (音频管理)](../reference/apis/js-apis-audio.md) 49 50 [@ohos.multimedia.media (媒体服务)](../reference/apis/js-apis-media.md) 51 52 53## 接口说明 54 55**表2** 延迟任务主要接口 56 57以下是延迟任务开发使用的相关接口,更多接口及使用方式请见[延迟任务](../reference/apis/js-apis-resourceschedule-workScheduler.md)文档。 58| 接口名 | 接口描述 | 59| -------- | -------- | 60| startWork(work: WorkInfo): void; | 申请延迟任务 | 61| stopWork(work: WorkInfo, needCancel?: boolean): void; | 取消延迟任务 | 62| getWorkStatus(workId: number, callback: AsyncCallback<WorkInfo>): void; | 获取延迟任务状态(Callback形式) | 63| getWorkStatus(workId: number): Promise<WorkInfo>; | 获取延迟任务状态(Promise形式) | 64| obtainAllWorks(callback: AsyncCallback<void>): Array<WorkInfo>; | 获取所有延迟任务(Callback形式) | 65| obtainAllWorks(): Promise<Array<WorkInfo>>; | 获取所有延迟任务(Promise形式) | 66| stopAndClearWorks(): void; | 停止并清除任务 | 67| isLastWorkTimeOut(workId: number, callback: AsyncCallback<void>): boolean; | 获取上次任务是否超时(针对RepeatWork,Callback形式) | 68| isLastWorkTimeOut(workId: number): Promise<boolean>; | 获取上次任务是否超时(针对RepeatWork,Promise形式) | 69 70**表3** WorkInfo参数 71| 参数名 | 类型 | 描述 | 72| -------- | -------- | -------- | 73| workId | number | 延迟任务Id(必填) | 74| bundleName | string | 延迟任务包名(必填) | 75| abilityName | string | 延迟任务回调通知的组件名(必填) | 76| networkType | [NetworkType](../reference/apis/js-apis-resourceschedule-workScheduler.md#networktype) | 网络类型 | 77| isCharging | boolean | 是否充电 | 78| chargerType | [ChargingType](../reference/apis/js-apis-resourceschedule-workScheduler.md#chargingtype) | 充电类型 | 79| batteryLevel | number | 电量 | 80| batteryStatus | [BatteryStatus](../reference/apis/js-apis-resourceschedule-workScheduler.md#batterystatus) | 电池状态 | 81| storageRequest | [StorageRequest](../reference/apis/js-apis-resourceschedule-workScheduler.md#storagerequest) | 存储状态 | 82| isRepeat | boolean | 是否循环任务 | 83| repeatCycleTime | number | 循环间隔 | 84| repeatCount | number | 循环次数 | 85| parameters | [key: string]: number | 携带参数信息 | 86 87WorkInfo参数用于设置应用条件,参数设置时需遵循以下规则: 88 89- workId、bundleName、abilityName为必填项,bundleName需为本应用包名。 90 91- 携带参数信息仅支持number、string、bool三种类型。 92 93- 至少设置一个满足的条件,包括网络类型、充电类型、存储状态、电池状态、定时状态等。 94 95- 对于重复任务,任务执行间隔至少20分钟。设置重复任务时间间隔时,须同时设置是否循环或循环次数中的一个。 96 97**表4** 延迟任务回调接口 98 99以下是延迟任务回调开发使用的相关接口,更多接口及使用方式请见[延迟任务回调](../reference/apis/js-apis-WorkSchedulerExtensionAbility.md)文档。 100| 接口名 | 接口描述 | 101| -------- | -------- | 102| onWorkStart(work: WorkInfo): void | 延迟调度任务开始的回调 | 103| onWorkStop(work: WorkInfo): void | 延迟调度任务结束的回调 | 104 105 106## 开发步骤 107 108延迟任务调度开发步骤分为两步:实现延迟任务调度扩展能力、实现延迟任务调度。 109 1101. **延迟任务调度扩展能力**:实现WorkSchedulerExtensionAbility开始和结束的回调接口。 111 1122. **延迟任务调度**:调用延迟任务接口,实现延迟任务申请、取消等功能。 113 114### 实现延迟任务回调拓展能力 115 1161. 新建工程目录。 117 118 在工程entry Module对应的ets目录(./entry/src/main/ets)下,新建目录及ArkTS文件,例如新建一个目录并命名为extension。在extension目录下,新建一个ArkTS文件并命名为WorkSchedulerExtension.ets,用以实现延迟任务回调接口。 119 1202. 导入模块。 121 122 ```ts 123 import WorkSchedulerExtensionAbility from '@ohos.WorkSchedulerExtensionAbility'; 124 ``` 125 1263. 实现WorkSchedulerExtension生命周期接口。 127 128 ```ts 129 export default class MyWorkSchedulerExtensionAbility extends WorkSchedulerExtensionAbility { 130 // 延迟任务开始回调 131 onWorkStart(workInfo) { 132 console.info(`onWorkStart, workInfo = ${JSON.stringify(workInfo)}`); 133 } 134 135 // 延迟任务结束回调 136 onWorkStop(workInfo) { 137 console.info(`onWorkStop, workInfo is ${JSON.stringify(workInfo)}`); 138 } 139 } 140 ``` 141 1424. 在[module.json5配置文件](../quick-start/module-configuration-file.md)中注册WorkSchedulerExtensionAbility,并设置如下标签: 143 144 - type标签设置为“workScheduler”。 145 146 - srcEntry标签设置为当前ExtensionAbility组件所对应的代码路径。 147 148 ```json 149 { 150 "module": { 151 "extensionAbilities": [ 152 { 153 "name": "MyWorkSchedulerExtensionAbility", 154 "srcEntry": "./ets/WorkSchedulerExtension/WorkSchedulerExtension.ets", 155 "label": "$string:WorkSchedulerExtensionAbility_label", 156 "description": "$string:WorkSchedulerExtensionAbility_desc", 157 "type": "workScheduler" 158 } 159 ] 160 } 161 } 162 ``` 163 164 165### 实现延迟任务调度 166 1671. 导入模块。 168 169 ```ts 170 import workScheduler from '@ohos.resourceschedule.workScheduler'; 171 ``` 172 1732. 申请延迟任务。 174 175 ```ts 176 private workInfo = { 177 workId: 1, 178 networkType: workScheduler.NetworkType.NETWORK_TYPE_WIFI, 179 bundleName: 'com.example.application', 180 abilityName: 'MyWorkSchedulerExtensionAbility' 181 } 182 183 try { 184 workScheduler.startWork(this.workInfo); 185 console.info(`startWork success`); 186 } catch (error) { 187 console.error(`startWork failed. code is ${error.code} message is ${error.message}`); 188 } 189 ``` 190 1913. 取消延迟任务。 192 193 ```ts 194 private workInfo = { 195 workId: 1, 196 networkType: workScheduler.NetworkType.NETWORK_TYPE_WIFI, 197 bundleName: 'com.example.application', 198 abilityName: 'MyWorkSchedulerExtensionAbility' 199 } 200 201 try { 202 workScheduler.stopWork(this.workInfo); 203 console.info(`stopWork success`); 204 } catch (error) { 205 console.error(`stopWork failed. code is ${error.code} message is ${error.message}`); 206 } 207 ``` 208 209## 相关实例 210 211针对延迟任务调度的开发,有以下相关示例可供参考: 212 213- [延迟任务调度(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/OpenHarmony-3.2-Release/code/BasicFeature/TaskManagement/WorkScheduler)