If an application needs to execute a non-real-time task after switching to the background, for example, if the application wants to obtain emails irregularly when the network is available, the application can request deferred tasks. When the specified trigger conditions (including the network type, charging type, storage status, battery status, and timing status) are met, the system adds the task to the execution queue. Then the system starts the application to execute the deferred task based on the memory, power consumption, device temperature, and user habits.
Figure 1 Working principle of deferred task scheduling

An application calls the deferred task API to add, delete, and query deferred tasks. The deferred task management module determines the scheduling time based on the task conditions (set by the WorkInfo parameter, including the network type, charging type, and storage status) and system status (including the memory, power consumption, device temperature, and user habits).
When the scheduling conditions are met or the task scheduling ends, the system calls back onWorkStart() or onWorkStop() in WorkSchedulerExtensionAbility. The system also creates an independent process for the WorkSchedulerExtensionAbility and sets a period for the WorkSchedulerExtensionAbility to run. You can implement your own service logic in the callback functions.
Quantity limit: An application can request a maximum of 10 deferred tasks during a time segment.
Execution frequency limit: The system controls the execution frequency of deferred tasks application activity group.
Table 1 Application activity groups
| Group | Deferred Task Execution Frequency |
|---|---|
| Group of active applications | At a minimum interval of 2 hours |
| Group of frequently used applications | At a minimum interval of 4 hours |
| Group of commonly used applications | At a minimum interval of 24 hours |
| Group of rarely used applications | At a minimum interval of 48 hours |
| Group of restricted applications | Forbidden |
| Group of applications never used | Forbidden |
Timeout: The WorkSchedulerExtensionAbility can run for a maximum of 2 minutes for a single callback. If the application does not cancel the deferred task upon a timeout, the system forcibly terminates the process for the WorkSchedulerExtensionAbility.
Scheduling delay: The system schedules deferred tasks in a unified manner based on the memory, power consumption, device temperature, and user habits. For example, when the system memory resources are insufficient or the temperature reaches a certain level, the system delays task scheduling.
For details about the restrictions on calling WorkSchedulerExtensionAbility APIs, see Constraints.
Table 2 Main APIs for deferred tasks
The table below lists the APIs used for developing deferred tasks. For details about more APIs and their usage, see @ohos.resourceschedule.workScheduler (Deferred Task Scheduling).
| API | Description |
|---|---|
| startWork(work: WorkInfo): void | Start a deferred task. |
| stopWork(work: WorkInfo, needCancel?: boolean): void | Cancel the deferred task. |
| getWorkStatus(workId: number, callback: AsyncCallback<WorkInfo>): void | Obtains the information about a deferred task. This API uses an asynchronous callback to return the result. |
| getWorkStatus(workId: number): Promise<WorkInfo> | Obtains the information about a deferred task. This API uses a promise to return the result. |
| obtainAllWorks(callback: AsyncCallback<Array<WorkInfo>>): void | Obtains all the deferred tasks. This API uses an asynchronous callback to return the result. |
| obtainAllWorks(): Promise<Array<WorkInfo>> | Obtains all the deferred tasks. This API uses a promise to return the result. |
| stopAndClearWorks(): void | Stops and clears all the deferred tasks. |
| isLastWorkTimeOut(workId: number, callback: AsyncCallback<boolean>): void | Checks whether the last execution of a deferred task has timed out. This API uses an asynchronous callback to return the result. It is applicable to repeated tasks. |
| isLastWorkTimeOut(workId: number): Promise<boolean> | Checks whether the last execution of a deferred task has timed out. This API uses a promise to return the result. It is applicable to repeated tasks. |
Table 3 Deferred task scheduling callback APIs
The table below lists the APIs used for developing deferred task scheduling callbacks. For details about more APIs and their usage, see @ohos.WorkSchedulerExtensionAbility (Deferred Task Scheduling Callbacks).
| API | Description |
|---|---|
| onWorkStart(work: workScheduler.WorkInfo): void | Called when the system starts scheduling the deferred task. |
| onWorkStop(work: workScheduler.WorkInfo): void | Called when the system stops scheduling the deferred task. |
The development of deferred task scheduling consists of two steps: implementing the deferred task scheduling capability and implementing deferred task scheduling.
Implementing the deferred task scheduling capability: Implement the callback APIs for starting and stopping the WorkSchedulerExtensionAbility.
Implementing deferred task scheduling: Call the WorkScheduler APIs to start and stop deferred tasks.
Create a project directory.
In the ./entry/src/main/ets directory of the project, create a directory and an ArkTS file. For example, create a directory and name it WorkSchedulerAbility. In the WorkSchedulerAbility directory, create an ArkTS file named WorkSchedulerAbility.ets and implement the callback APIs for deferred task scheduling.
Import the module. No permission is required.
import {workScheduler, WorkSchedulerExtensionAbility} from '@kit.BackgroundTasksKit'; Implement the lifecycle callbacks for the WorkSchedulerExtensionAbility.
export default class WorkSchedulerAbility extends WorkSchedulerExtensionAbility {
// Callback invoked when the system starts scheduling the deferred task.
onWorkStart(workInfo: workScheduler.WorkInfo) {
// ...
console.info(`onWorkStart, workInfo = ${JSON.stringify(workInfo)}`);
// Print the parameter, for example, key1, in parameters.
console.info(`work info parameters: ${JSON.parse(workInfo.parameters?.toString()).key1}`);
}
// Callback invoked when the deferred task ends. This callback is triggered when the deferred task times out for 2 minutes or the stopWork API is called to cancel the task.
onWorkStop(workInfo: workScheduler.WorkInfo) {
console.info(`onWorkStop, workInfo is ${JSON.stringify(workInfo)}`);
}
} Register the WorkSchedulerExtensionAbility in the module.json5 file and set the tags as follows:
Set type to workScheduler.
Set srcEntry to the code path of the WorkSchedulerExtensionAbility component.
{
"module": {
// ...
"extensionAbilities": [
{
"name": "WorkSchedulerAbility",
"srcEntry": "./ets/WorkSchedulerAbility/WorkSchedulerAbility.ets",
"type": "workScheduler",
// ...
}
]
}
} Import the module.
import { BusinessError } from '@kit.BasicServicesKit';
import { workScheduler } from '@kit.BackgroundTasksKit'; Request a deferred task.
let workInfo: workScheduler.WorkInfo = {
workId: 1,
networkType: workScheduler.NetworkType.NETWORK_TYPE_ANY,
bundleName: 'ohos.samples.workschedulerextensionability',
abilityName: 'WorkSchedulerAbility',
// ...
}
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}`);
} Cancel the deferred task.
// Create workInfo.
let workInfo: workScheduler.WorkInfo = {
workId: 1,
networkType: workScheduler.NetworkType.NETWORK_TYPE_ANY,
bundleName: 'ohos.samples.workschedulerextensionability',
abilityName: 'WorkSchedulerAbility',
// ...
}
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}`);
} Check whether the onWorkStart and onWorkStop methods of WorkSchedulerExtensionAbility are correctly implemented and can be successfully called.
After the deferred task is requested, its callback can be triggered only when the required conditions are met. To quickly perform the verification, trigger the callback manually using the following hidumper command.
$ hidumper -s 1904 -a '-t com.example.application MyWorkSchedulerExtensionAbility' -------------------------------[ability]------------------------------- ----------------------------------WorkSchedule----------------------------------