# 延迟任务(ArkTS) ## 概述 ### åŠŸèƒ½ä»‹ç» åº”ç”¨é€€è‡³åŽå°åŽï¼Œéœ€è¦æ‰§è¡Œå®žæ—¶æ€§è¦æ±‚ä¸é«˜çš„任务,例如有网络时ä¸å®šæœŸä¸»åŠ¨èŽ·å–邮件ç‰ï¼Œå¯ä»¥ä½¿ç”¨å»¶è¿Ÿä»»åŠ¡ã€‚å½“åº”ç”¨æ»¡è¶³è®¾å®šæ¡ä»¶ï¼ˆåŒ…括网络类型ã€å……电类型ã€å˜å‚¨çжæ€ã€ç”µæ± 状æ€ã€å®šæ—¶çжæ€ç‰ï¼‰æ—¶ï¼Œå°†ä»»åŠ¡æ·»åŠ åˆ°æ‰§è¡Œé˜Ÿåˆ—ï¼Œç³»ç»Ÿä¼šæ ¹æ®å†…å˜ã€åŠŸè€—ã€è®¾å¤‡æ¸©åº¦ã€ç”¨æˆ·ä½¿ç”¨ä¹ 惯ç‰ç»Ÿä¸€è°ƒåº¦æ‹‰èµ·åº”用。 ### è¿è¡ŒåŽŸç† **图1** å»¶è¿Ÿä»»åŠ¡å®žçŽ°åŽŸç†  åº”ç”¨è°ƒç”¨å»¶è¿Ÿä»»åŠ¡æŽ¥å£æ·»åŠ ã€åˆ é™¤ã€æŸ¥è¯¢å»¶è¿Ÿä»»åŠ¡ï¼Œå»¶è¿Ÿä»»åŠ¡ç®¡ç†æ¨¡å—ä¼šæ ¹æ®ä»»åŠ¡è®¾ç½®çš„æ¡ä»¶ï¼ˆé€šè¿‡WorkInfo傿•°è®¾ç½®ï¼ŒåŒ…括网络类型ã€å……电类型ã€å˜å‚¨çжæ€ç‰ï¼‰å’Œç³»ç»Ÿçжæ€ï¼ˆåŒ…括内å˜ã€åŠŸè€—ã€è®¾å¤‡æ¸©åº¦ã€ç”¨æˆ·ä½¿ç”¨ä¹ 惯ç‰ï¼‰ç»Ÿä¸€å†³ç–调度时机。 当满足调度æ¡ä»¶æˆ–è°ƒåº¦ç»“æŸæ—¶ï¼Œç³»ç»Ÿä¼šå›žè°ƒåº”用[WorkSchedulerExtensionAbility](../reference/apis-backgroundtasks-kit/js-apis-WorkSchedulerExtensionAbility.md)ä¸ onWorkStart() 或 onWorkStop() çš„æ–¹æ³•ï¼ŒåŒæ—¶ä¼šä¸ºåº”用å•独创建一个Extension扩展进程用以承载[WorkSchedulerExtensionAbility](../reference/apis-backgroundtasks-kit/js-apis-WorkSchedulerExtensionAbility.md),并给[WorkSchedulerExtensionAbility](../reference/apis-backgroundtasks-kit/js-apis-WorkSchedulerExtensionAbility.md)一定的活动周期,开å‘者å¯ä»¥åœ¨å¯¹åº”回调方法ä¸å®žçŽ°è‡ªå·±çš„ä»»åŠ¡é€»è¾‘ã€‚ ### 约æŸä¸Žé™åˆ¶ - **æ•°é‡é™åˆ¶**:一个应用åŒä¸€æ—¶åˆ»æœ€å¤šç”³è¯·10个延迟任务。 - **执行频率é™åˆ¶**ï¼šç³»ç»Ÿä¼šæ ¹æ®<!--RP1-->[设备使用信æ¯ç»Ÿè®¡](../reference/apis-backgroundtasks-kit/js-apis-resourceschedule-deviceUsageStatistics-sys.md)应用的活跃分组<!--RP1End-->,对延迟任务åšåˆ†çº§ç®¡æŽ§ï¼Œé™åˆ¶å»¶è¿Ÿä»»åŠ¡è°ƒåº¦çš„æ‰§è¡Œé¢‘çŽ‡ã€‚<!--Del-->é€šè¿‡èƒ½æ•ˆèµ„æºæŽ¥å£ç”³è¯·äº†WORK_SCHEDULER资æºçš„应用,会被放在能效资æºè±å…分组ä¸ã€‚<!--DelEnd--> **表1** 应用活跃程度分组 | 应用活跃分组 | 延迟任务执行频率 | | -------- | -------- | | 活跃分组 | 最å°é—´éš”2å°æ—¶ | | ç»å¸¸ä½¿ç”¨åˆ†ç»„ | 最å°é—´éš”4å°æ—¶ | | 常用使用 | 最å°é—´éš”24å°æ—¶ | | æžå°‘使用分组 | 最å°é—´éš”48å°æ—¶ | | å—é™ä½¿ç”¨åˆ†ç»„ | ç¦æ¢ | | 从未使用分组 | ç¦æ¢ |<!--Del--> | 能效资æºè±å…分组 | ä¸å—é™åˆ¶ |<!--DelEnd--> - **è¶…æ—¶**:WorkSchedulerExtensionAbility啿¬¡å›žè°ƒæœ€é•¿è¿è¡Œ2分钟。如果超时ä¸å–消,系统会终æ¢å¯¹åº”çš„Extension进程。<!--Del-->对于系统特æƒåº”用,å¯ä»¥é€šè¿‡èƒ½æ•ˆèµ„æºæŽ¥å£ç”³è¯·WORK_SCHEDULER资æºï¼Œæ‰©å±•啿¬¡å›žè°ƒè¿è¡Œæ—¶é•¿ï¼Œæ‰©å±•åŽåœ¨å……电状æ€ä¸‹ä¸º20分钟,éžå……电状æ€ä¸‹ä¸º10分钟。<!--DelEnd--> - **调度延迟**ï¼šç³»ç»Ÿä¼šæ ¹æ®å†…å˜ã€åŠŸè€—ã€è®¾å¤‡æ¸©åº¦ã€ç”¨æˆ·ä½¿ç”¨ä¹ 惯ç‰ç»Ÿä¸€è°ƒåº¦ï¼Œå¦‚当系统内å˜èµ„æºä¸è¶³æˆ–æ¸©åº¦è¾¾åˆ°ä¸€å®šæŒ¡ä½æ—¶ï¼Œç³»ç»Ÿå°†å»¶è¿Ÿè°ƒåº¦è¯¥ä»»åŠ¡ã€‚ - **WorkSchedulerExtensionAbility接å£è°ƒç”¨é™åˆ¶**:为实现对WorkSchedulerExtensionAbility能力的管控,在WorkSchedulerExtensionAbilityä¸é™åˆ¶ä»¥ä¸‹æŽ¥å£çš„调用: [@ohos.resourceschedule.backgroundTaskManager (åŽå°ä»»åŠ¡ç®¡ç†)](../reference/apis-backgroundtasks-kit/js-apis-resourceschedule-backgroundTaskManager.md) [@ohos.backgroundTaskManager (åŽå°ä»»åŠ¡ç®¡ç†)](../reference/apis-backgroundtasks-kit/js-apis-backgroundTaskManager.md) [@ohos.multimedia.camera (相机管ç†)](../reference/apis-camera-kit/js-apis-camera.md) [@ohos.multimedia.audio (音频管ç†)](../reference/apis-audio-kit/js-apis-audio.md) [@ohos.multimedia.media (媒体æœåŠ¡)](../reference/apis-media-kit/js-apis-media.md) ## 接å£è¯´æ˜Ž **表2** å»¶è¿Ÿä»»åŠ¡ä¸»è¦æŽ¥å£ ä»¥ä¸‹æ˜¯å»¶è¿Ÿä»»åŠ¡å¼€å‘使用的相关接å£ï¼Œæ›´å¤šæŽ¥å£åŠä½¿ç”¨æ–¹å¼è¯·è§[延迟任务调度](../reference/apis-backgroundtasks-kit/js-apis-resourceschedule-workScheduler.md)文档。 | 接å£å | æŽ¥å£æè¿° | | -------- | -------- | | startWork(work: WorkInfo): void; | 申请延迟任务 | | stopWork(work: WorkInfo, needCancel?: boolean): void; | å–æ¶ˆå»¶è¿Ÿä»»åŠ¡ | | getWorkStatus(workId: number, callback: AsyncCallback<WorkInfo>): void; | 获å–延迟任务状æ€ï¼ˆCallbackå½¢å¼ï¼‰ | | getWorkStatus(workId: number): Promise<WorkInfo>; | 获å–延迟任务状æ€ï¼ˆPromiseå½¢å¼ï¼‰ | | obtainAllWorks(callback: AsyncCallback\<Array\<WorkInfo>>): void; | èŽ·å–æ‰€æœ‰å»¶è¿Ÿä»»åŠ¡ï¼ˆCallbackå½¢å¼ï¼‰ | | obtainAllWorks(): Promise<Array<WorkInfo>>; | èŽ·å–æ‰€æœ‰å»¶è¿Ÿä»»åŠ¡ï¼ˆPromiseå½¢å¼ï¼‰ | | stopAndClearWorks(): void; | åœæ¢å¹¶æ¸…除任务 | | isLastWorkTimeOut(workId: number, callback: AsyncCallback\<boolean>): void; | 获å–上次任务是å¦è¶…时(针对RepeatWork,Callbackå½¢å¼ï¼‰ | | isLastWorkTimeOut(workId: number): Promise<boolean>; | 获å–上次任务是å¦è¶…时(针对RepeatWork,Promiseå½¢å¼ï¼‰ | **表3** WorkInfo傿•° | åç§° | 类型 | å¿…å¡« | 说明 | | --------------- | --------------------------------- | ---- | ---------------- | | workId | number | 是 | 延迟任务ID。 | | bundleName | string | 是 | 延迟任务所在应用的包å。 | | abilityName | string | 是 | 包内abilityå称。 | | networkType | [NetworkType](../reference/apis-backgroundtasks-kit/js-apis-resourceschedule-workScheduler.md#networktype) | å¦ | 网络类型。 | | isCharging | boolean | å¦ | 是å¦å……电。<br>- true表示充电触å‘延迟回调,false表示ä¸å……电触å‘延迟回调。| | chargerType | [ChargingType](../reference/apis-backgroundtasks-kit/js-apis-resourceschedule-workScheduler.md#chargingtype) | å¦ | 充电类型。 | | batteryLevel | number | å¦ | 电é‡ã€‚ | | batteryStatus | [BatteryStatus](../reference/apis-backgroundtasks-kit/js-apis-resourceschedule-workScheduler.md#batterystatus) | å¦ | ç”µæ± çŠ¶æ€ã€‚ | | storageRequest | [StorageRequest](../reference/apis-backgroundtasks-kit/js-apis-resourceschedule-workScheduler.md#storagerequest) | å¦ | å˜å‚¨çжæ€ã€‚ | | isRepeat | boolean | å¦ | 是å¦å¾ªçŽ¯ä»»åŠ¡ã€‚<br>- true表示循环任务,false表示éžå¾ªçŽ¯ä»»åŠ¡ã€‚ | | repeatCycleTime | number | å¦ | 循环间隔,å•ä½ä¸ºæ¯«ç§’。 | | repeatCount | number | å¦ | 循环次数。 | | isPersisted | boolean | å¦ | 注册的延迟任务是å¦å¯ä¿å˜åœ¨ç³»ç»Ÿä¸ã€‚<br>- true表示å¯ä¿å˜ï¼Œå³ç³»ç»Ÿé‡å¯åŽï¼Œä»»åС坿¢å¤ã€‚false表示ä¸å¯ä¿å˜ã€‚| | isDeepIdle | boolean | å¦ | 是å¦è¦æ±‚设备进入空闲状æ€ã€‚<br>- true表示需è¦ï¼Œfalse表示ä¸éœ€è¦ã€‚ | | idleWaitTime | number | å¦ | 空闲ç‰å¾…时间,å•ä½ä¸ºæ¯«ç§’。 | | parameters | [key: string]: number \| string \| boolean | å¦ | æºå¸¦å‚æ•°ä¿¡æ¯ã€‚ | WorkInfo傿•°ç”¨äºŽè®¾ç½®åº”用æ¡ä»¶ï¼Œå‚数设置时需éµå¾ªä»¥ä¸‹è§„则: - workIdã€bundleNameã€abilityName为必填项,bundleName需为本应用包å。 - æºå¸¦å‚æ•°ä¿¡æ¯ä»…支æŒnumberã€stringã€boolean三ç§ç±»åž‹ã€‚ - 至少设置一个满足的æ¡ä»¶ï¼ŒåŒ…括网络类型ã€å……电类型ã€å˜å‚¨çжæ€ã€ç”µæ± 状æ€ã€å®šæ—¶çжæ€ç‰ã€‚ - 对于é‡å¤ä»»åŠ¡ï¼Œä»»åŠ¡æ‰§è¡Œé—´éš”è‡³å°‘2å°æ—¶ã€‚设置é‡å¤ä»»åŠ¡æ—¶é—´é—´éš”æ—¶ï¼Œé¡»åŒæ—¶è®¾ç½®æ˜¯å¦å¾ªçŽ¯æˆ–å¾ªçŽ¯æ¬¡æ•°ä¸çš„一个。 **表4** å»¶è¿Ÿä»»åŠ¡å›žè°ƒæŽ¥å£ ä»¥ä¸‹æ˜¯å»¶è¿Ÿä»»åŠ¡å›žè°ƒå¼€å‘使用的相关接å£ï¼Œæ›´å¤šæŽ¥å£åŠä½¿ç”¨æ–¹å¼è¯·è§[延迟任务调度回调](../reference/apis-backgroundtasks-kit/js-apis-WorkSchedulerExtensionAbility.md)文档。 | 接å£å | æŽ¥å£æè¿° | | -------- | -------- | | onWorkStart(work: workScheduler.WorkInfo): void | 延迟调度任务开始的回调 | | onWorkStop(work: workScheduler.WorkInfo): void | 延迟调度任务结æŸçš„回调 | ## 开呿¥éª¤ å»¶è¿Ÿä»»åŠ¡è°ƒåº¦å¼€å‘æ¥éª¤åˆ†ä¸ºä¸¤æ¥ï¼šå®žçŽ°å»¶è¿Ÿä»»åŠ¡è°ƒåº¦æ‰©å±•èƒ½åŠ›ã€å®žçŽ°å»¶è¿Ÿä»»åŠ¡è°ƒåº¦ã€‚ 1. **延迟任务调度扩展能力**:实现WorkSchedulerExtensionAbility开始和结æŸçš„回调接å£ã€‚ 2. **延迟任务调度**:调用延迟任务接å£ï¼Œå®žçŽ°å»¶è¿Ÿä»»åŠ¡ç”³è¯·ã€å–消ç‰åŠŸèƒ½ã€‚ ### 实现延迟任务回调拓展能力 1. 新建工程目录。 在工程entry Module对应的ets目录(./entry/src/main/ets)下,新建目录åŠArkTS文件,例如新建一个目录并命å为WorkSchedulerExtension。在WorkSchedulerExtension目录下,新建一个ArkTS文件并命å为WorkSchedulerExtension.ets,用以实现延迟任务回调接å£ã€‚ 2. 导入模å—。 ```ts import { WorkSchedulerExtensionAbility, workScheduler } from '@kit.BackgroundTasksKit'; ``` 3. 实现WorkSchedulerExtension生命周期接å£ã€‚ ```ts 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}`) } // 延迟任务结æŸå›žè°ƒ onWorkStop(workInfo: workScheduler.WorkInfo) { console.info(`onWorkStop, workInfo is ${JSON.stringify(workInfo)}`); } } ``` 4. 在[module.json5é…置文件](../quick-start/module-configuration-file.md)䏿³¨å†ŒWorkSchedulerExtensionAbilityï¼Œå¹¶è®¾ç½®å¦‚ä¸‹æ ‡ç¾ï¼š - typeæ ‡ç¾è®¾ç½®ä¸ºâ€œworkSchedulerâ€ã€‚ - srcEntryæ ‡ç¾è®¾ç½®ä¸ºå½“å‰ExtensionAbility组件所对应的代ç 路径。 ```json { "module": { "extensionAbilities": [ { "name": "MyWorkSchedulerExtensionAbility", "srcEntry": "./ets/WorkSchedulerExtension/WorkSchedulerExtension.ets", "type": "workScheduler" } ] } } ``` ### 实现延迟任务调度 1. 导入模å—。 ```ts import { workScheduler } from '@kit.BackgroundTasksKit'; import { BusinessError } from '@kit.BasicServicesKit'; ``` 2. 申请延迟任务。 ```ts // 创建workinfo const workInfo: workScheduler.WorkInfo = { workId: 1, networkType: workScheduler.NetworkType.NETWORK_TYPE_WIFI, bundleName: 'com.example.application', abilityName: 'MyWorkSchedulerExtensionAbility' } try { workScheduler.startWork(workInfo); console.info(`startWork success`); } catch (error) { console.error(`startWork failed. code is ${(error as BusinessError).code} message is ${(error as BusinessError).message}`); } ``` 3. å–æ¶ˆå»¶è¿Ÿä»»åŠ¡ã€‚ ```ts // 创建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}`); } ``` ## 相关实例 针对延迟任务调度的开å‘,有以下相关示例å¯ä¾›å‚考: - [延迟任务调度(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/TaskManagement/WorkScheduler)