From 44f920113930fad376a5111ad028ed1bc27d7b0d Mon Sep 17 00:00:00 2001 From: Gloria Date: Thu, 19 Jan 2023 15:40:44 +0800 Subject: [PATCH] Update docs against TR13577 Signed-off-by: wusongqing --- .../task-management/Readme-EN.md | 4 +- .../background-task-overview.md | 78 ++++--- .../continuous-task-dev-guide.md | 16 +- .../figures/WorkSchedulerExtensionAbility.png | Bin 0 -> 56139 bytes .../bgtask_choice.png | Bin .../reminder-agent-development.md | 50 ++--- .../transient-task-dev-guide.md | 86 ++++---- .../work-scheduler-dev-guide.md | 51 ++--- .../workscheduler-extensionability.md | 196 ++++++++++++++++++ 9 files changed, 338 insertions(+), 143 deletions(-) create mode 100644 en/application-dev/task-management/figures/WorkSchedulerExtensionAbility.png rename en/application-dev/task-management/{public_sys-resources => figures}/bgtask_choice.png (100%) create mode 100644 en/application-dev/task-management/workscheduler-extensionability.md diff --git a/en/application-dev/task-management/Readme-EN.md b/en/application-dev/task-management/Readme-EN.md index f4b1d6d548..8f5c8d9045 100644 --- a/en/application-dev/task-management/Readme-EN.md +++ b/en/application-dev/task-management/Readme-EN.md @@ -5,9 +5,9 @@ - [Transient Task Development](transient-task-dev-guide.md) - [Continuous Task Development](continuous-task-dev-guide.md) - [Work Scheduler Development](work-scheduler-dev-guide.md) + - [WorkSchedulerExtensionAbility Development](workscheduler-extensionability.md) - [Efficiency Resource Request Development](efficiency-resources-apply-dev-guide.md) - Agent-Powered Scheduled Reminder - [Agent-Powered Reminder Overview](reminder-agent-overview.md) - - [Agent-Powered Reminder Development](reminder-agent-development.md) - + - [Agent-Powered Reminder Development](reminder-agent-development.md) \ No newline at end of file diff --git a/en/application-dev/task-management/background-task-overview.md b/en/application-dev/task-management/background-task-overview.md index 201c666ad7..dc7e7e3eda 100644 --- a/en/application-dev/task-management/background-task-overview.md +++ b/en/application-dev/task-management/background-task-overview.md @@ -1,26 +1,26 @@ # Background Task Management Overview Frequent activities of background applications cause user devices to consume power quickly and respond slowly. To meet performance and power consumption requirements, the system allows applications in the background to execute only activities within the specifications. Activities beyond the specifications are suspended by default, and resources allocated to them will be reclaimed when the available resources are insufficient. -If an application or a service module running in the background has a service to continue, it can request a [transient task](#transient-tasks) to delay the suspension or a [continuous task](#continuous-tasks) to prevent the suspension. If an application needs to execute a non-real-time task when running in the background, it can request a [Work Scheduler Task](#work-scheduler-tasks). A privileged application can also request [efficiency resources](#efficiency-resources) for more flexibility. +If an application or a service module running in the background has a service to continue, it can request a [transient task](#transient-tasks) to delay the suspension or a [continuous task](#continuous-tasks) to prevent the suspension. If an application needs to execute a non-real-time task when running in the background, it can request a [Work Scheduler task](#work-scheduler-tasks). A privileged application can also request [efficiency resources](#efficiency-resources) for more flexibility. ## Background Task Types For more targeted management of background applications, OpenHarmony classifies background tasks into the following types and provides an extended resource request mode: -**No background task**: An application or service module does not need further processing when switched to the background. +- **No background task**: An application or service module does not need further processing when switched to the background. -**Transient task**: If an application or service module has an urgent, short task that must continue in the background until it is completed, such as data compression, the application or service module can request a transient task for delayed suspension. +- **Transient task**: If an application or service module has an urgent, short task that must continue in the background until it is completed, such as data compression, the application or service module can request a transient task for delayed suspension. -**Continuous task**: If an application or service module has a user-initiated, perceivable task that needs to run in an extended period of time in the background, it can request a continuous task so that it will not be suspended. Examples of continuous tasks include music playback, navigation, device connection, and VoIP. +- **Continuous task**: If an application or service module has a user-initiated, perceivable task that needs to run in an extended period of time in the background, it can request a continuous task so that it will not be suspended. Examples of continuous tasks include music playback, navigation, device connection, and VoIP. -**Work Scheduler task**: The Work Scheduler provides a mechanism for applications to execute non-real-time tasks when the system is idle. If the preset conditions are met, the tasks will be placed in the execution queue and scheduled when the system is idle. +- **Work Scheduler task**: The Work Scheduler provides a mechanism for applications to execute non-real-time tasks when the system is idle. If the preset conditions are met, the tasks will be placed in the execution queue and scheduled when the system is idle. -**Efficiency resources**: If an application needs to ensure that it will not be suspended within a period of time or can normally use certain system resources when it is suspended, it can request efficiency resources, including CPU, WORK_SCHEDULER, software, and hardware resources. Different types of efficiency resources come with different privileges. For example, the CPU resources enable an application or process to keep running without being suspended, and the WORK_SCHEDULER resources allow for more task execution time before the application or process is suspended. +- **Efficiency resources**: If an application needs to ensure that it will not be suspended within a period of time or can normally use certain system resources when it is suspended, it can request efficiency resources, including CPU, WORK_SCHEDULER, software, and hardware resources. Different types of efficiency resources come with different privileges. For example, the CPU resources enable an application or process to keep running without being suspended, and the WORK_SCHEDULER resources allow for more task execution time before the application or process is suspended. ## Selecting a Background Task -![Background Task Selection](public_sys-resources/bgtask_choice.png) +![Background Task Selection](figures/bgtask_choice.png) ## Transient Tasks @@ -51,17 +51,17 @@ OpenHarmony provides 9 background modes for services that require continuous tas **Table 1** Background modes for continuous tasks -| Background Mode| Description| Hint in Notification Panel| Remarks| -| -------- | -------- | -------- | -------- | -| dataTransfer | Data transfer through the network or peer device, such as download, backup, share, and transfer| A data transfer task is running.| - | -| audioPlayback | Audio output| An audio playback task is running.| - | -| audioRecording | Audio input| A recording task is running.| - | -| location | Positioning and navigation| A positioning task is running.| - | -| bluetoothInteraction | Bluetooth transmission| A Bluetooth-related task is running.| - | -| multiDeviceConnection | Distributed interconnection| A distributed task is running.| - | -| wifiInteraction | WLAN transmission| A WLAN-related task is running.| System API, which is available only to system applications| -| voip | Voice and video calls over VoIP| A call-related task is running.| System API, which is available only to system applications| -| taskKeeping | Computing task| A computing task is running| Effective only for specific devices| +| Background Mode | Description | Hint in Notification Panel | Remarks | +| --------------------- | ------------------------- | ------------ | ------------------------- | +| dataTransfer | Data transfer through the network or peer device, such as download, backup, share, and transfer| A data transfer task is running. | - | +| audioPlayback | Audio output | An audio playback task is running. | - | +| audioRecording | Audio input | A recording task is running. | - | +| location | Positioning and navigation | A positioning task is running. | - | +| bluetoothInteraction | Bluetooth transmission | A Bluetooth-related task is running. | - | +| multiDeviceConnection | Distributed interconnection | A distributed task is running. | - | +| wifiInteraction | WLAN transmission | A WLAN-related task is running.| System API, which is available only to system applications| +| voip | Voice and video calls over VoIP | A call-related task is running. | System API, which is available only to system applications| +| taskKeeping | Computing task | A computing task is running | Effective only for specific devices | ### Restrictions on Using Continuous Tasks - If a user triggers a perceivable task, such as broadcasting and navigation, the corresponding background mode is triggered. When the task is started, the system forcibly displays a notification to the user. @@ -80,15 +80,15 @@ The use of the Work Scheduler must comply with the following restrictions and ru - **Timeout**: The Work Scheduler callback can run only within the specified period of time. After the timeout, the callback automatically stops. The default timeout duration is 2 minutes. System applications can request [efficiency resources](efficiency-resources-apply-dev-guide.md) to obtain a longer duration (20 minutes in the charging state and 10 minutes in the non-charging state). - **Execution frequency**: The system controls the execution frequency of Work Scheduler tasks based on the activity level of their respective applications. If an application has applied for the WORK_SCHEDULER resources through the efficiency resource API, the execution frequency is not limited within the validity period of the resources. - | Application Group | Work Scheduler Task Execution Frequency | - | --------------------|------------------------- | - | Active| At a minimum interval of 2 hours| - | Used every day| At a minimum interval of 4 hours| - | Frequently used| At a minimum interval of 24 hours| - | Infrequently used| At a minimum interval of 48 hours| - | Restricted| Prohibited| - | Unused| Prohibited| - | [Exemption group for efficiency resources](../reference/apis/js-apis-backgroundTaskManager.md#resourcetype9) | Unlimited| + | Application Group | Work Scheduler Task Execution Frequency| + | ---------------------------------------- | ---------- | + | Active | At a minimum interval of 2 hours | + | Used every day | At a minimum interval of 4 hours | + | Frequently used | At a minimum interval of 24 hours | + | Infrequently used | At a minimum interval of 48 hours | + | Restricted | Prohibited | + | Unused | Prohibited | + | [Exemption group for efficiency resources](../reference/apis/js-apis-resourceschedule-backgroundTaskManager.md#resourcetype)| Unlimited | - **WorkInfo setting** @@ -110,25 +110,21 @@ An application or process is assigned the privileges associated with the obtaine * With the TIMER resources, the application can use the timer to execute precise scheduled tasks. * With the hardware resources, the application can still be woken up by related services to execute tasks when it is suspended in the background. + **Table 2** Efficiency resource types -| Name | Value | Description | -| ----------------------- | ---- | --------------------- | -| CPU | 1 | CPU resources, which prevent the application from being suspended. | -| COMMON_EVENT | 2 | A type of software resources, which prevent common events from being proxied when the application is suspended. | -| TIMER | 4 | A type of software resources, which prevent timers from being proxied when the application is suspended. | -| WORK_SCHEDULER | 8 | WORK_SCHEDULER resources, which ensure that the application has more time to execute the task. | -| BLUETOOTH | 16 | A type of hardware resources, which prevent Bluetooth resources from being proxied when the application is suspended. | -| GPS | 32 | A type of hardware resources, which prevent GPS resources from being proxied when the application is suspended. | -| AUDIO | 64 | A type of hardware resources, which prevent audio resources from being proxied when the application is suspended.| +| Name | Value | Description | +| -------------- | ---- | ------------------- | +| CPU | 1 | CPU resources, which prevent the application from being suspended. | +| COMMON_EVENT | 2 | A type of software resources, which prevent common events from being proxied when the application is suspended. | +| TIMER | 4 | A type of software resources, which prevent timers from being proxied when the application is suspended. | +| WORK_SCHEDULER | 8 | WORK_SCHEDULER resources, which ensure that the application has more time to execute the task. | +| BLUETOOTH | 16 | A type of hardware resources, which prevent Bluetooth resources from being proxied when the application is suspended. | +| GPS | 32 | A type of hardware resources, which prevent GPS resources from being proxied when the application is suspended.| +| AUDIO | 64 | A type of hardware resources, which prevent audio resources from being proxied when the application is suspended. | ### Restrictions on Using Efficiency Resources - Applications or processes are responsible for requesting and releasing efficiency resources. A process can release the resources requested by itself, whereas an application can release the resources requested by both itself and its processes. For example, an application requests CPU resources, and its process requests CPU and WORK_SCHEDULER resources. If the application initiates CPU resource release, the CPU resources requested by the process are also released. However, the WORK_SCHEDULER resources are not released. If the process initiates CPU resource release, the CPU resources requested by the application are retained until being released by the application. - - If persistent resources and non-persistent resources of the same type are requested, the persistent resources overwrite the non-persistent resources and they will not be released upon a timeout. For example, if an application first requests 10-second CPU resources and then requests persistent CPU resources at the 5th second, the CPU resources become persistent and will not be released at the tenth second. If the application releases the CPU resources at the 8th second, both types of CPU resources are released. - - The WORK_SCHEDULER resources can be requested and released by applications, but not by processes. - - To use efficiency resources, an application must first submit a request to the application center to obtain corresponding privileges. - - diff --git a/en/application-dev/task-management/continuous-task-dev-guide.md b/en/application-dev/task-management/continuous-task-dev-guide.md index 5ec27a6e13..2613b4d7ac 100644 --- a/en/application-dev/task-management/continuous-task-dev-guide.md +++ b/en/application-dev/task-management/continuous-task-dev-guide.md @@ -3,7 +3,7 @@ ## When to Use If an application has a perceivable task that needs to run in an extended period of time in the background, it can request a continuous task so that it will not be suspended. Examples of continuous tasks include music playback, navigation, device connection, and VoIP. -There is no time limit for a continuous task running in the background. To prevent abuse, the system limits the number of continuous tasks that can be requested. It also attaches a notification to the task so that the task is perceivable. In addition, the system verifies whether the application is actually executing the continuous task. +There is no time limit for a continuous task running in the background. To prevent abuse, the system limits the number of continuous tasks that can be requested. It also attaches a notification to each of the tasks so that the tasks are perceivable. In addition, the system verifies whether the application is actually executing a continuous task. ## Available APIs @@ -34,9 +34,9 @@ For details about **wantAgent**, see [WantAgent](../reference/apis/js-apis-wantA ## How to Develop -### Development on the FA Model +### Development in the FA Model -For details about how to use the Service ability in the FA model, see [Service Ability Development](../ability/fa-serviceability.md). +For details about how to use the ServiceAbility in the FA model, see [ServiceAbility Component Overview](../application-models/serviceability-overview.md). If an application does not need to interact with a continuous task in the background, you can use **startAbility()** to start the Service ability. In the **onStart** callback of the Service ability, call **startBackgroundRunning()** to declare that the Service ability needs to run in the background for a long time. After the task execution is complete, call **stopBackgroundRunning()** to release resources. @@ -177,9 +177,9 @@ export default { }; ``` -### Development on the Stage Model +### Development in the Stage Model -For details about the stage model, see [Stage Model Overview](../ability/stage-brief.md). +For details about the stage model, see [Stage Model Development Overview](../application-models/stage-model-development-overview.md). 1. Create an API version 9 project. Then right-click the project directory and choose **New > Ability** to create an ability. Configure the continuous task permission (ohos.permission.KEEP_BACKGROUND_RUNNING) and background mode type in the **module.json5** file. @@ -201,7 +201,7 @@ For details about the stage model, see [Stage Model Overview](../ability/stage-b } ``` -2. If an application needs to execute a continuous task for its own, include the execution logic in the Page ability. This is because an application cannot use **startAbilityByCall** to create and run its own ability in the background due to the restriction of ability startup controls. For details about how to use an ability in the stage model, see [Ability Development](../ability/stage-ability.md). +2. If an application needs to execute a continuous task for its own, include the execution logic in the Page ability. This is because an application cannot use **startAbilityByCall** to create and run its own ability in the background due to the restriction of ability startup controls. For details, see [UIAbility Component Overview](../application-models/uiability-overview.md). ```ts import wantAgent from '@ohos.wantAgent'; @@ -290,7 +290,7 @@ struct Index { } ``` -3. If a continuous task needs to be executed in the background for another application or on another device, you can create and run an ability in the background in Call mode. For details, see [Call Development](../ability/stage-call.md). +3. If a continuous task needs to be executed in the background for another application or on another device, you can create and run an ability in the background in Call mode. For details, see [Using Ability Call (Intra-Device)](../application-models/uiability-intra-device-interaction.md#using-ability-call-to-implement-uiability-interaction) and [Using Ability Call (Inter-Device)](../application-models/hop-multi-device-collaboration.md#using-cross-device-ability-call). ```ts import Ability from '@ohos.application.Ability' @@ -420,4 +420,4 @@ export default class BgTaskAbility extends Ability { console.info("[Demo] BgTaskAbility onBackground") } }; -``` +``` \ No newline at end of file diff --git a/en/application-dev/task-management/figures/WorkSchedulerExtensionAbility.png b/en/application-dev/task-management/figures/WorkSchedulerExtensionAbility.png new file mode 100644 index 0000000000000000000000000000000000000000..627a88f515e8a4ba1beb40e3242fd3521cb39494 GIT binary patch literal 56139 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 B>v;eG literal 0 HcmV?d00001 diff --git a/en/application-dev/task-management/public_sys-resources/bgtask_choice.png b/en/application-dev/task-management/figures/bgtask_choice.png similarity index 100% rename from en/application-dev/task-management/public_sys-resources/bgtask_choice.png rename to en/application-dev/task-management/figures/bgtask_choice.png diff --git a/en/application-dev/task-management/reminder-agent-development.md b/en/application-dev/task-management/reminder-agent-development.md index c749a9f4cc..6cd2d5e294 100644 --- a/en/application-dev/task-management/reminder-agent-development.md +++ b/en/application-dev/task-management/reminder-agent-development.md @@ -5,16 +5,16 @@ The agent-powered reminder feature provides APIs for publishing background reminders. You can call these APIs to create scheduled reminders for countdown timers, calendar events, and alarm clocks. The APIs are encapsulated in the [reminderAgentManager](../reference/apis/js-apis-reminderAgentManager.md) class. -**Table 1** Major APIs in reminderAgentManager + **Table 1** Major APIs in reminderAgentManager -| API | Description | -| ------------------------------------------------------------ | ------------------------------------------------------------ | -| publishReminder(reminderReq: ReminderRequest, callback: AsyncCallback<number>): void
publishReminder(reminderReq: ReminderRequest): Promise<number> | Publishes a scheduled reminder.
The maximum number of valid notifications (excluding expired ones that will not pop up again) is 30 for one application and 2000 for the entire system. | -| cancelReminder(reminderId: number, callback: AsyncCallback<void>): void
cancelReminder(reminderId: number): Promise<void> | Cancels a specified reminder. (The value of **reminderId** is obtained from the return value of **publishReminder**.) | -| getValidReminders(callback: AsyncCallback<Array<ReminderRequest>>): void
getValidReminders(): Promise<Array<ReminderRequest>> | Obtains all valid reminders set by the current application. | -| cancelAllReminders(callback: AsyncCallback<void>): void
cancelAllReminders(): Promise<void> | Cancels all reminders set by the current application. | -| addNotificationSlot(slot: NotificationSlot, callback: AsyncCallback<void>): void
addNotificationSlot(slot: NotificationSlot): Promise<void> | Registers a **NotificationSlot** instance to be used by the reminder. | -| removeNotificationSlot(slotType: notification.SlotType, callback: AsyncCallback<void>): void
removeNotificationSlot(slotType: notification.SlotType): Promise<void> | Removes a **NotificationSlot** instance of a specified type. | +| API | Description | +| ---------------------------------------- | ---------------------------------------- | +| publishReminder(reminderReq: ReminderRequest, callback: AsyncCallback<number>): void
publishReminder(reminderReq: ReminderRequest): Promise<number> | Publishes a scheduled reminder.
The maximum number of valid notifications (excluding expired ones that will not pop up again) is 30 for one application
and 2000 for the entire system.| +| cancelReminder(reminderId: number, callback: AsyncCallback<void>): void
cancelReminder(reminderId: number): Promise<void> | Cancels a specified reminder. (The value of **reminderId** is obtained from the return value of **publishReminder**.)| +| getValidReminders(callback: AsyncCallback<Array<ReminderRequest>>): void
getValidReminders(): Promise<Array<ReminderRequest>> | Obtains all valid reminders set by the current application. | +| cancelAllReminders(callback: AsyncCallback<void>): void
cancelAllReminders(): Promise<void> | Cancels all reminders set by the current application. | +| addNotificationSlot(slot: NotificationSlot, callback: AsyncCallback<void>): void
addNotificationSlot(slot: NotificationSlot): Promise<void> | Registers a **NotificationSlot** instance to be used by the reminder. | +| removeNotificationSlot(slotType: notification.SlotType, callback: AsyncCallback<void>): void
removeNotificationSlot(slotType: notification.SlotType): Promise<void> | Removes a **NotificationSlot** instance of a specified type. | ## How to Develop @@ -27,7 +27,7 @@ The agent-powered reminder feature provides APIs for publishing background remin ```js import reminderAgentManager from '@ohos.reminderAgentManager'; - import notificationManager from '@ohos.notificationManager'; + import NotificationManager from '@ohos.notificationManager'; ``` 4. Define a reminder agent. You can define the following types of reminder agents based on project requirements. @@ -51,11 +51,11 @@ The agent-powered reminder feature provides APIs for publishing background remin pkgName: 'com.example.myapplication', abilityName: 'EntryAbility' }, - title:'this is title', // Reminder title. - content:'this is content', // Reminder content. - expiredContent:'This reminder has expired', // Content to be displayed after the reminder expires. + title: 'this is title', // Reminder title. + title: 'this is title', // Reminder content. + expiredContent: 'this reminder has expired', // Content to be displayed after the reminder expires. notificationId: 100, // Notification ID used by the reminder. If there are reminders with the same notification ID, the later one will overwrite the earlier one. - slotType: notificationManager.SlotType.SOCIAL_COMMUNICATION // Type of the slot used by the reminder. + slotType: NotificationManager.SlotType.SOCIAL_COMMUNICATION // Type of the slot used by the reminder. } ``` - Calendar event @@ -94,12 +94,12 @@ The agent-powered reminder feature provides APIs for publishing background remin ringDuration: 5, // Ringing duration, in seconds. snoozeTimes: 2, // Number of reminder snooze times. timeInterval: 5, // Reminder snooze interval, in seconds. - title:'this is title', // Reminder title. + title: 'this is title', // Reminder title. content:'this is content', // Reminder content. - expiredContent:'This reminder has expired', // Content to be displayed after the reminder expires. - snoozeContent:'remind later', // Content to be displayed when the reminder is snoozed. + expiredContent: 'this reminder has expired', // Content to be displayed after the reminder expires. + snoozeContent: 'remind later', // Content to be displayed when the reminder is snoozed. notificationId: 100, // Notification ID used by the reminder. If there are reminders with the same notification ID, the later one will overwrite the earlier one. - slotType: notificationManager.SlotType.SOCIAL_COMMUNICATION // Type of the slot used by the reminder. + slotType: NotificationManager.SlotType.SOCIAL_COMMUNICATION // Type of the slot used by the reminder. } ``` - Alarm clock @@ -131,12 +131,12 @@ The agent-powered reminder feature provides APIs for publishing background remin ringDuration: 5, // Ringing duration, in seconds. snoozeTimes: 2, // Number of reminder snooze times. timeInterval: 5, // Reminder snooze interval, in seconds. - title:'this is title', // Reminder title. - content:'this is content', // Reminder content. - expiredContent:'This reminder has expired', // Content to be displayed after the reminder expires. - snoozeContent:'remind later', // Content to be displayed when the reminder is snoozed. + title: 'this is title', // Reminder title. + content: 'this is content', // Reminder content. + expiredContent: 'this reminder has expired', // Content to be displayed after the reminder expires. + snoozeContent: 'remind later', // Content to be displayed when the reminder is snoozed. notificationId: 99, // Notification ID used by the reminder. If there are reminders with the same notification ID, the later one will overwrite the earlier one. - slotType: notificationManager.SlotType.SOCIAL_COMMUNICATION // Type of the slot used by the reminder. + slotType: NotificationManager.SlotType.SOCIAL_COMMUNICATION // Type of the slot used by the reminder. } ``` @@ -175,7 +175,3 @@ The agent-powered reminder feature provides APIs for publishing background remin console.log("cancelReminder code: " + error.code + ", message: " + error.message); }; ``` - - - - \ No newline at end of file diff --git a/en/application-dev/task-management/transient-task-dev-guide.md b/en/application-dev/task-management/transient-task-dev-guide.md index b1e815fc68..193c243864 100644 --- a/en/application-dev/task-management/transient-task-dev-guide.md +++ b/en/application-dev/task-management/transient-task-dev-guide.md @@ -2,12 +2,11 @@ ## When to Use -By default, an application can run for 6 to 12 seconds after it switches to the background but before being suspended. If an application requires more time to execute an important task, it can call the **requestSuspendDelay** API to delay the suspension. +By default, an application can run for a period of 6 to 12 seconds after it switches to the background. When this period expires, the application is suspended. If an application requires more time to execute an important task, it can call the **requestSuspendDelay** API to request a transient task to delay the suspension. -It is recommended that an application calls the **requestSuspendDelay** API before executing any time-consuming task, rather than when it is already running in the background. -The calling of the **requestSuspendDelay** API when the application is running in the foreground does not affect the transient task quota of the application. +You are advised not to call the **requestSuspendDelay()** method to apply for delayed suspension after the application is running in the background. Instead, you need to call this interface to declare the execution time of the extended application to the system before performing any time-consuming operation. It is recommended that an application calls **requestSuspendDelay()** when it is running in the foreground, so as not to affect the transient task quota of the application. -Each application has a daily time quota for transient tasks. Therefore, after the time-consuming task finishes execution, the application should cancel the transient task in a timely manner. +An application can obtain the remaining duration before being suspended by calling [getRemainingDelayTime()](../reference/apis/js-apis-resourceschedule-backgroundTaskManager.md#backgroundtaskmanagergetremainingdelaytimecallback). Each application has a daily time quota for transient tasks. Therefore, after the time-consuming task finishes execution, the application should call [cancelSuspendDelay()](../reference/apis/js-apis-resourceschedule-backgroundTaskManager.md#backgroundtaskmanagercancelsuspenddelay) to cancel the transient task in a timely manner. Typical time-consuming tasks include saving status data to the local database, opening and processing a large file, and synchronizing data to the cloud server. @@ -19,67 +18,74 @@ Typical time-consuming tasks include saving status data to the local database, o | API | Description | | ---------------------------------------- | ---------------------------------------- | -| requestSuspendDelay(reason: string, callback: Callback<void>): [DelaySuspendInfo](../reference/apis/js-apis-backgroundTaskManager.md#delaysuspendinfo) | Requests delayed suspension after the application switches to the background.
The default duration value of delayed suspension is 3 minutes when the battery level is normal and 1 minute when the battery level is low.| +| requestSuspendDelay(reason: string, callback: Callback<void>): [DelaySuspendInfo](../reference/apis/js-apis-backgroundTaskManager.md#delaysuspendinfo)| Requests delayed suspension after the application switches to the background.
The default duration of delayed suspension is 3 minutes when the battery level is normal and 1 minute when the battery level is low.| | getRemainingDelayTime(requestId: number): Promise<number> | Obtains the remaining duration before the application is suspended.
This API uses a promise to return the result. | | cancelSuspendDelay(requestId: number): void | Cancels the suspension delay. | ## How to Develop -1. When an application needs to execute a time-consuming task, call the API to request a transient task. After the time-consuming task finishes execution, call the API to cancel the transient task. +When an application needs to execute a time-consuming task in the background, call the API to request a transient task. After the time-consuming task finishes execution, call the API to cancel the transient task. ```js -import backgroundTaskManager from '@ohos.backgroundTaskManager'; +import backgroundTaskManager from '@ohos.resourceschedule.backgroundTaskManager'; -let delayInfo; -let id; +let id; // ID of the suspension delay request. +let delayTime; // Remaining duration for the suspension delay request. // Request a suspension delay. function requestSuspendDelay() { - let myReason = 'test requestSuspendDelay'; - delayInfo = backgroundTaskManager.requestSuspendDelay(myReason, () => { - console.info("Request suspension delay will time out."); - // The callback in invoked to notify the application that the suspension delay request is about to time out. The application needs to perform some cleanup and annotation operations. - }); - + let myReason = 'test requestSuspendDelay'; // Reason for the suspension delay request. + + try { + let delayInfo = backgroundTaskManager.requestSuspendDelay(myReason, () => { + // The callback is invoked to notify the application that the suspension delay request is about to time out. The application needs to perform some cleanup and annotation operations and cancels the transient task. + console.info("[backgroundTaskManager] Request suspension delay will time out."); + backgroundTaskManager.cancelSuspendDelay(id); + }) id = delayInfo.requestId; - console.info("requestId is: " + id); + delayTime = delayInfo.actualDelayTime; + console.info("[backgroundTaskManager] The requestId is: " + id); + console.info("[backgroundTaskManager]The actualDelayTime is: " + delayTime); + } catch (error) { + console.error(`[backgroundTaskManager] requestSuspendDelay failed. code is ${error.code} message is ${error.message}`); + } } // Obtain the remaining duration before the application is suspended. -function getRemainingDelayTime() { - let delayTime = 0; - backgroundTaskManager.getRemainingDelayTime(id).then((res) => { - console.log('promise => Operation getRemainingDelayTime succeeded. Data: ' + JSON.stringify(res)); - delayTime = res; - }).catch((err) => { - console.log('promise => Operation getRemainingDelayTime failed. Cause: ' + err.code); - }); - return delayTime; +async function getRemainingDelayTime() { + try { + await backgroundTaskManager.getRemainingDelayTime(id).then(res => { + console.log('[backgroundTaskManager] promise => Operation getRemainingDelayTime succeeded. Data: ' + JSON.stringify(res)); + }).catch(error => { + console.error(`[backgroundTaskManager] promise => Operation getRemainingDelayTime failed. code is ${error.code} message is ${error.message}`); + }) + } catch (error) { + console.error(`[backgroundTaskManager] promise => Operation getRemainingDelayTime failed. code is ${error.code} message is ${error.message}`); + } } // Cancel the suspension delay. function cancelSuspendDelay() { - backgroundTaskManager.cancelSuspendDelay(id); + backgroundTaskManager.cancelSuspendDelay(id); } -function performingLongRunningTask() { - // Before executing the time-consuming task, call the API to request a transient task to delay the suspension. - requestSuspendDelay(); - - // Obtain the available time quota through the getRemainingDelayTime() API. - let delayTime = getRemainingDelayTime(); +async function performingLongRunningTask() { + // Before executing a time-consuming task, call the API to request a transient task to delay the suspension. + requestSuspendDelay(); - if (delayTime < 0) {// If the time is less than a certain value, cancel the time-consuming operation. - // Handle the scenario where the time quota is insufficient. + // If required, obtain the available time quota through the getRemainingDelayTime() API. + await getRemainingDelayTime(); - cancelSuspendDelay(); - return; - } + if (delayTime < 0) {// If the time is less than a certain value, cancel the time-consuming task. + // Handle the scenario where the time quota is insufficient. + cancelSuspendDelay(); + return; + } - // Execute the time-consuming task. + // Execute the time-consuming task. - // After the time-consuming task is executed, call the API to cancel the transient task. - cancelSuspendDelay(); + // After the time-consuming task is executed, call the API to cancel the transient task. + cancelSuspendDelay(); } ``` diff --git a/en/application-dev/task-management/work-scheduler-dev-guide.md b/en/application-dev/task-management/work-scheduler-dev-guide.md index 6ab36ea5da..845423ee6f 100644 --- a/en/application-dev/task-management/work-scheduler-dev-guide.md +++ b/en/application-dev/task-management/work-scheduler-dev-guide.md @@ -2,7 +2,7 @@ ## When to Use -If your application needs to execute a non-real-time task or a persistent task, for example, data learning, you can harness the Work Scheduler mechanism, which will schedule the task based on the storage space, power consumption, temperature, and more when the preset conditions are met. For details about the restrictions, see [Restrictions on Using Work Scheduler](./background-task-overview.md#restrictions-on-using-work-scheduler). +If your application needs to execute a non-real-time task or a persistent task, for example, data learning, you can harness the Work Scheduler mechanism, which will schedule the task based on the storage space, power consumption, temperature, and more when the preset conditions are met. Your application must implement the callbacks provided by [WorkSchedulerExtensionAbility](./workscheduler-extensionability.md) for Work Scheduler tasks. For details about the restrictions, see [Restrictions on Using Work Scheduler](./background-task-overview.md#restrictions-on-using-work-scheduler). ## Available APIs @@ -14,21 +14,21 @@ startWork(work: WorkInfo): void; | Starts a Work Scheduler task. stopWork(work: WorkInfo, needCancel?: boolean): void; | Stops a Work Scheduler task. getWorkStatus(workId: number, callback: AsyncCallback\): void;| Obtains the status of a Work Scheduler task. This API uses an asynchronous callback to return the result. getWorkStatus(workId: number): Promise\; | Obtains the status of a Work Scheduler task. This API uses a promise to return the result. -obtainAllWorks(callback: AsyncCallback\): Array\;| Obtains Work Scheduler tasks. This API uses an asynchronous callback to return the result. -obtainAllWorks(): Promise>;| Obtains Work Scheduler tasks. This API uses a promise to return the result. -stopAndClearWorks(): void;| Stops and clears Work Scheduler tasks. +obtainAllWorks(callback: AsyncCallback\): Array\;| Obtains all the Work Scheduler tasks. This API uses an asynchronous callback to return the result. +obtainAllWorks(): Promise>;| Obtains all the Work Scheduler tasks. This API uses a promise to return the result. +stopAndClearWorks(): void;| Stops and clears all the Work Scheduler tasks. isLastWorkTimeOut(workId: number, callback: AsyncCallback\): boolean;| Checks whether the last execution of the specified task has timed out. This API uses an asynchronous callback to return the result. It is applicable to repeated tasks. isLastWorkTimeOut(workId: number): Promise\;| Checks whether the last execution of the specified task has timed out. This API uses a promise to return the result. It is applicable to repeated tasks. **Table 2** WorkInfo parameters -For details about the constraints on configuring **WorkInfo**, see [Restrictions on Using Work Scheduler](./background-task-overview.md#restrictions-on-using-work-scheduler). +For details about the restriction on configuring **WorkInfo**, see [Restrictions on Using Work Scheduler](./background-task-overview.md#restrictions-on-using-work-scheduler). Name| Type|Description ---------------------------------------------------------|-----------------------------------------|--------------------------------------------------------- -workId| number | Work ID. Mandatory. -bundleName| string | Name of the Work Scheduler task bundle. Mandatory. -abilityName| string | Name of the component to be notified by a Work Scheduler callback. Mandatory. +workId| number | ID of the Work Scheduler task. Mandatory. +bundleName| string | Bundle name of the Work Scheduler task. Mandatory. +abilityName| string | Name of the ability to be notified by a Work Scheduler callback. Mandatory. networkType | [NetworkType](../reference/apis/js-apis-resourceschedule-workScheduler.md#networktype) | Network type. isCharging| boolean | Whether the device is charging. chargerType| [ChargingType](../reference/apis/js-apis-resourceschedule-workScheduler.md#chargingtype) | Charging type. @@ -42,26 +42,27 @@ parameters | {[key: string]: any} |Carried parameters. **Table 3** Work Scheduler callbacks -Name | Description +API | Description ---------------------------------------------------------|----------------------------------------- -onWorkStart(work: WorkInfo): void | Triggered when the Work Scheduler task starts. -onWorkStop(work: WorkInfo): void | Triggered when the Work Scheduler task stops. +onWorkStart(work: WorkInfo): void | Called when the Work Scheduler task starts. +onWorkStop(work: WorkInfo): void | Called when the Work Scheduler task stops. ### How to Develop 1. Import the modules. - Import the **workScheduler** package to implement registration: -```js -import workScheduler from '@ohos.resourceschedule.workScheduler'; -``` + Import the **workScheduler** module. + + ```js + import workScheduler from '@ohos.resourceschedule.workScheduler'; + ``` - Import the **WorkSchedulerExtensionAbility** package to implement callback: -```js -import WorkSchedulerExtensionAbility from '@ohos.WorkSchedulerExtensionAbility'; -``` + Import the **WorkSchedulerExtensionAbility** module. + ```js + import WorkSchedulerExtensionAbility from '@ohos.WorkSchedulerExtensionAbility'; + ``` -2. Develop an Extension ability to execute a Work Scheduler task. For details about the Extension ability, see [ExtensionAbility Mechanism](../ability/stage-brief.md#extensionability-mechanism). +2. Develop an ExtensionAbility to execute a Work Scheduler task. For details about the ExtensionAbility, see [ExtensionAbility Component Overview](../application-models/extensionability-overview.md) and [WorkSchedulerExtensionAbility Development](./workscheduler-extensionability.md). ```ts import WorkSchedulerExtensionAbility from '@ohos.WorkSchedulerExtensionAbility'; @@ -77,7 +78,7 @@ export default class MyExtension extends WorkSchedulerExtensionAbility { ``` -3. Register a Work Scheduler task. +3. Start a Work Scheduler task. ```ts import workScheduler from '@ohos.resourceschedule.workScheduler'; @@ -105,7 +106,7 @@ try{ ``` -4. Cancel the Work Scheduler task. +4. Stop the Work Scheduler task. ```ts import workScheduler from '@ohos.resourceschedule.workScheduler'; @@ -152,7 +153,7 @@ try{ ``` -6. Obtain all Work Scheduler tasks. +6. Obtain all the Work Scheduler tasks. ```ts try{ @@ -168,7 +169,7 @@ try{ } ``` -7. Stop and clear Work Scheduler tasks. +7. Stop and clear all the Work Scheduler tasks. ```ts try{ @@ -179,7 +180,7 @@ try{ } ``` -8. Check whether the last execution has timed out. +8. Check whether the last execution of a specified Work Scheduler task has timed out. ```ts try{ diff --git a/en/application-dev/task-management/workscheduler-extensionability.md b/en/application-dev/task-management/workscheduler-extensionability.md new file mode 100644 index 0000000000..9f7547fcb3 --- /dev/null +++ b/en/application-dev/task-management/workscheduler-extensionability.md @@ -0,0 +1,196 @@ +# WorkSchedulerExtensionAbility Development + +If your application needs to execute a non-real-time task or a persistent task, you can harness the Work Scheduler mechanism, which will schedule the task when the preset conditions (including the network type, charging type, storage status, battery status, and timing status) are met. + +**WorkSchedulerExtensionAbility** provides callbacks for Work Scheduler tasks. When a Work Scheduler task starts or stops, these callbacks are invoked to process your service logic. + +## Working Principles + +Figure 1 shows the working principle of Work Scheduler. + +**Figure 1** Work Scheduler working principle + +![WorkSchedulerExtensionAbility](figures/WorkSchedulerExtensionAbility.png) + +An application starts, stops, and obtains Work Scheduler tasks through the [workScheduler APIs](../reference/apis/js-apis-resourceschedule-workScheduler.md). It implements the task starting or stopping execution logic through the [Work Scheduler callbacks](../reference/apis/js-apis-WorkSchedulerExtensionAbility.md). + +The application service layer detects and determines the conditions. If the preset conditions are met, the application service layer calls back the **WorkSchedulerExtensionAbility** object to start the application and triggers the **onWorkStart** and **onWorkStop** callbacks. + +## Available APIs + +The **WorkSchedulerExtensionAbility** class has the following APIs. For details, see [WorkSchedulerExtensionAbility](../reference/apis/js-apis-WorkSchedulerExtensionAbility.md). + +| Name| Description| +| -------- | -------- | +| onWorkStart(work: workScheduler.WorkInfo): void | Called when the Work Scheduler task starts.| +| onWorkStop(work: workScheduler.WorkInfo): void | Called when the Work Scheduler task stops.| + +## How to Develop + +To create a WorkScheduler project in DevEco Studio, perform the following steps: + +- [Implement callbacks for Work Scheduler](#implementing-callbacks-for-work-scheduler): Develop the callbacks provided by **WorkSchedulerExtensionAbility**. + +- [Implement Work Scheduler](#implementing-work-scheduler): Develop the [workScheduler APIs] to implement functions such as starting or stopping Work Scheduler tasks. + +- [Set the configuration file](#setting-the-configuration-file): Set the configuration file **module.json5**. + +### Implementing Callbacks for Work Scheduler + +1. Create a module named **library** in the root directory of the project, with the **Ohos Library** template selected. + +2. In the **./library/src/main/ets** directory under **library**, create an ArkTS file named **workAbility.ets** and implement the callbacks for Work Scheduler. + + Import the module. + + ```ts + import WorkSchedulerExtensionAbility from '@ohos.WorkSchedulerExtensionAbility' + ``` + + Implement the lifecycle callbacks for the WorkSchedulerExtensionAbility. + + ```ts + export default class workAbility extends WorkSchedulerExtensionAbility { + // Callback invoked when the Work Scheduler task starts. + onWorkStart(workInfo) { + console.log(`onWorkStart CommonEvent publish start ${JSON.stringify(workInfo)}`) + // Publish an upgrade notification. + let notificationRequest = notification.getNotificationContentBasic('upgrade', upgradeMessage, '') + notification.publish(notificationRequest, (err) => { + if (err) { + console.log(`onWorkStart notification publish err ${JSON.stringify(err)}`) + } + console.log(`onWorkStart notification publish success`) + }) + } + + // Callback invoked when the Work Scheduler task stops. + onWorkStop(workInfo) { + // Publish an upgrade completion notification. + let notificationRequest = notification.getNotificationContentBasic('upgrade', 'upgrade success', '') + notification.publish(notificationRequest, (err) => { + if (err) { + console.log(`onWorkStop notification publish err ${JSON.stringify(err)}`) + } + console.log(`onWorkStop notification publish success`) + }) + } + } + ``` + +3. In the **./entry/src/main/ets** directory under the **entry** module of the project, create a directory named **workAbility**. In the **workAbility** directory, create an ArkTS file named **WorkTest.ets** and implement the callbacks for Work Scheduler. + +Import the module. + + ```ts + import { workAbility } from '@ohos/library' + ``` + +Inherit from **workAbility** and implement the lifecycle callbacks for the WorkSchedulerExtensionAbility. + + ```ts + export default class WorkTest extends workAbility { + onWorkStart(workInfo) { + console.log(`onWorkStartTest start ${JSON.stringify(workInfo)}`) + super.onWorkStart(workInfo) + } + + onWorkStopTest(workInfo) { + super.onWorkStop(workInfo) + console.log(`onWorkStop value`) + } + } + ``` + +### Implementing Work Scheduler + +1. In the **./library/src/main/ets** directory under **library**, create a TypeScript file named **DelayWork.ts**, and implement the Work Scheduler APIs. + + Import the module. + + ```ts + import workScheduler from '@ohos.resourceschedule.workScheduler' + ``` + + Encapsulate the APIs for starting and stopping Work Scheduler tasks. + + ```ts + export default class DelayWork { + private workInfo = { + workId: 1, + networkType: workScheduler.NetworkType.NETWORK_TYPE_WIFI, + bundleName: '', + abilityName: '' + } + // Start the Work Scheduler task. + startWork(bundleName: string, abilityName: string) { + this.workInfo.bundleName = bundleName + this.workInfo.abilityName = abilityName + try { + workScheduler.startWork(this.workInfo) + console.log(`startWork success`) + } catch (error) { + Logger.error(TAG, `startWork startwork failed. code is ${error.code} message is ${error.message}`) + prompt.showToast({ + message: `${error.message}` + }) + } + } + + // Stop the Work Scheduler task. + stopWork(bundleName: string, abilityName: string) { + this.workInfo.bundleName = bundleName + this.workInfo.abilityName = abilityName + workScheduler.stopWork(this.workInfo, false) + console.log(`stopWork`) + } + } + ``` + +2. In the **./entry/src/main/ets/pages/index.ets** directory under the **entry** module of the project, add the **Upgrade** button, which, when being clicked, will call the API encapsulated in **library** to start the Work Scheduler task. + + Import the module. + + ```ts + import { workAbility } from '@ohos/library' + ``` + + Add the **Upgrade** button, which, when being clicked, will call the API encapsulated in **library** to start the Work Scheduler task. In the API, **bundleName** and **abilityName** are passed in, where the value of **abilityName** is **WorkTest**. + + ```ts + Button($r('app.string.upgrade')) + .width('60%') + .height(40) + .fontSize(30) + .onClick(() => { + this.work.startWork('ohos.samples.workscheduler', 'WorkTest') + }) + ``` + + When the component is destructed, it calls the API to stop the Work Scheduler task. + + ```ts + aboutToDisappear() { + this.work.stopWork('ohos.samples.workscheduler', 'WorkTest') + } + ``` + +### Setting the Configuration File + +1. Register the WorkSchedulerExtensionAbility in the [module.json5 file](../quick-start/module-configuration-file.md) under the **entry** module. Set **type** to **workScheduler** and **srcEntrance** to the code path of the WorkSchedulerExtensionAbility component. + + ```json + { + "module": { + "extensionAbilities": [ + { + "name": "WorkTest", + "srcEntrance": "./ets/workAbility/WorkTest.ets", + "label": "$string:WorkSchedulerExtensionAbility_label", + "description": "$string:WorkSchedulerExtensionAbility_desc", + "type": "workScheduler" + } + ] + } + } + ``` -- GitLab