未验证 提交 30efe996 编写于 作者: O openharmony_ci 提交者: Gitee

!10630 全局资源调度子系统的开发者指南整改

Merge pull request !10630 from 张鑫/master
......@@ -5,6 +5,8 @@
设备使用信息统计,包括app usage/notification usage/system usage等使用统计。例如应用使用信息统计,用于保存和查询应用使用详情(app usage)、事件日志数据(event log)、应用分组(bundle group)情况。
部件缓存的应用记录(使用历史统计和使用事件记录)会在事件上报后30分钟内刷新到数据库持久化保存。
根据设备的使用信息统计接口,开发者可以开发出健康管理类应用来实现个人设备健康使用功能,并向用户展示其个人设备的使用记录。
## 接口说明
注册相关接口包导入:
```js
......@@ -56,7 +58,6 @@ import stats from '@ohos.bundleState';
```js
import stats from '@ohos.bundleState'
// 异步方法promise方式
stats.queryBundleActiveStates(0, 20000000000000).then(res => {
console.log('BUNDLE_ACTIVE queryBundleActiveStates promise success.');
for (let i = 0; i < res.length; i++) {
......@@ -66,19 +67,6 @@ import stats from '@ohos.bundleState';
}).catch(err => {
console.log('BUNDLE_ACTIVE queryBundleActiveStates promise failed, because: ' + err.code);
});
// 异步方法callback方式
stats.queryBundleActiveStates(0, 20000000000000, (err, res) => {
if (err) {
console.log('BUNDLE_ACTIVE queryBundleActiveStates callback failed, because: ' + err.code);
} else {
console.log('BUNDLE_ACTIVE queryBundleActiveStates callback success.');
for (let i = 0; i < res.length; i++) {
console.log('BUNDLE_ACTIVE queryBundleActiveStates callback number : ' + (i + 1));
console.log('BUNDLE_ACTIVE queryBundleActiveStates callback result ' + JSON.stringify(res[i]));
}
}
});
```
3. 通过指定起始和结束时间查询应用使用时长统计信息,config.json中需要配置权限:ohos.permission.BUNDLE_ACTIVE_INFO。
......@@ -86,7 +74,6 @@ import stats from '@ohos.bundleState';
```js
import stats from '@ohos.bundleState'
// 异步方法promise方式
stats.queryBundleStateInfos(0, 20000000000000).then(res => {
console.log('BUNDLE_ACTIVE queryBundleStateInfos promise success.');
let i = 1;
......@@ -98,21 +85,6 @@ import stats from '@ohos.bundleState';
}).catch(err => {
console.log('BUNDLE_ACTIVE queryBundleStateInfos promise failed, because: ' + err.code);
});
// 异步方法callback方式
stats.queryBundleStateInfos(0, 20000000000000, (err, res) => {
if (err) {
console.log('BUNDLE_ACTIVE queryBundleStateInfos callback failed, because: ' + err.code);
} else {
console.log('BUNDLE_ACTIVE queryBundleStateInfos callback success.');
let i = 1;
for(let key in res){
console.log('BUNDLE_ACTIVE queryBundleStateInfos callback number : ' + i);
console.log('BUNDLE_ACTIVE queryBundleStateInfos callback result ' + JSON.stringify(res[key]));
i++;
}
}
});
```
4. 通过指定起始和结束时间查询当前应用的事件集合,config.json中不需要配置权限。
......@@ -120,7 +92,6 @@ import stats from '@ohos.bundleState';
```js
import stats from '@ohos.bundleState'
// 异步方法promise方式
stats.queryCurrentBundleActiveStates(0, 20000000000000).then(res => {
console.log('BUNDLE_ACTIVE queryCurrentBundleActiveStates promise success.');
for (let i = 0; i < res.length; i++) {
......@@ -130,19 +101,6 @@ import stats from '@ohos.bundleState';
}).catch(err => {
console.log('BUNDLE_ACTIVE queryCurrentBundleActiveStates promise failed, because: ' + err.code);
});
// 异步方法callback方式
stats.queryCurrentBundleActiveStates(0, 20000000000000, (err, res) => {
if (err) {
console.log('BUNDLE_ACTIVE queryCurrentBundleActiveStates callback failed, because: ' + err.code);
} else {
console.log('BUNDLE_ACTIVE queryCurrentBundleActiveStates callback success.');
for (let i = 0; i < res.length; i++) {
console.log('BUNDLE_ACTIVE queryCurrentBundleActiveStates callback number : ' + (i + 1));
console.log('BUNDLE_ACTIVE queryCurrentBundleActiveStates callback result ' + JSON.stringify(res[i]));
}
}
});
```
5. 通过指定时间段间隔(天、周、月、年)查询应用使用时长统计信息,config.json中需要配置权限:ohos.permission.BUNDLE_ACTIVE_INFO。
......@@ -150,7 +108,6 @@ import stats from '@ohos.bundleState';
```js
import stats from '@ohos.bundleState'
// 异步方法promise方式
stats.queryBundleStateInfoByInterval(0, 0, 20000000000000).then(res => {
console.log('BUNDLE_ACTIVE queryBundleStateInfoByInterval promise success.');
for (let i = 0; i < res.length; i++) {
......@@ -161,18 +118,6 @@ import stats from '@ohos.bundleState';
console.log('BUNDLE_ACTIVE queryBundleStateInfoByInterval promise failed, because: ' + err.code);
});
// 异步方法callback方式
stats.queryBundleStateInfoByInterval(0, 0, 20000000000000, (err, res) => {
if (err) {
console.log('BUNDLE_ACTIVE queryBundleStateInfoByInterval callback failed, because: ' + err.code);
} else {
console.log('BUNDLE_ACTIVE queryBundleStateInfoByInterval callback success.');
for (let i = 0; i < res.length; i++) {
console.log('BUNDLE_ACTIVE queryBundleStateInfoByInterval callback number : ' + (i + 1));
console.log('BUNDLE_ACTIVE queryBundleStateInfoByInterval callback result ' + JSON.stringify(res[i]));
}
}
});
```
6. 查询(无参)当前调用者应用的使用优先级群组,config.json中不需要配置权限。
......@@ -180,43 +125,24 @@ import stats from '@ohos.bundleState';
```js
import stats from '@ohos.bundleState'
// promise方式
stats.queryAppUsagePriorityGroup().then(res => {
console.log('BUNDLE_ACTIVE queryAppUsagePriorityGroup promise succeeded. result: ' + JSON.stringify(res));
}).catch(err => {
console.log('BUNDLE_ACTIVE queryAppUsagePriorityGroup promise failed. because: ' + err.code);
});
// callback方式
stats.queryAppUsagePriorityGroup((err, res) => {
if (err) {
console.log('BUNDLE_ACTIVE queryAppUsagePriorityGroup callback failed. because: ' + err.code);
} else {
console.log('BUNDLE_ACTIVE queryAppUsagePriorityGroup callback succeeded. result: ' + JSON.stringify(res));
}
});
```
7. 判断指定Bundle Name的应用当前是否是空闲状态,config.json中不需要配置权限,三方应用只能查询自身的空闲状态。
7. 判断指定Bundle Name的应用当前是否是空闲状态,config.json中需要配置权限:ohos.permission.BUNDLE_ACTIVE_INFO,三方应用只能查询自身的空闲状态。
```js
import stats from '@ohos.bundleState'
// 异步方法promise方式
stats.isIdleState("com.ohos.camera").then(res => {
console.log('BUNDLE_ACTIVE isIdleState promise succeeded, result: ' + JSON.stringify(res));
}).catch(err => {
console.log('BUNDLE_ACTIVE isIdleState promise failed, because: ' + err.code);
});
// 异步方法callback方式
stats.isIdleState("com.ohos.camera", (err, res) => {
if (err) {
console.log('BUNDLE_ACTIVE isIdleState callback failed, because: ' + err.code);
} else {
console.log('BUNDLE_ACTIVE isIdleState callback succeeded, result: ' + JSON.stringify(res));
}
});
```
8. 查询FA使用记录。返回数量最大不超过maxNum设置的值,若不传入maxNum参数,则默认maxNum为1000。config.json中需要配置权限:ohos.permission.BUNDLE_ACTIVE_INFO。
......@@ -245,32 +171,6 @@ import stats from '@ohos.bundleState';
}).catch( err=> {
console.log('BUNDLE_ACTIVE getRecentlyUsedModules promise failed, because: ' + err.code);
});
// 异步方法callback方式
stats.getRecentlyUsedModules(1000, (err, res) => {
if(err) {
console.log('BUNDLE_ACTIVE getRecentlyUsedModules callback failed, because: ' + err.code);
} else {
console.log('BUNDLE_ACTIVE getRecentlyUsedModules callback succeeded.');
for (let i = 0; i < res.length; i++) {
console.log('BUNDLE_ACTIVE getRecentlyUsedModules callback number : ' + (i + 1));
console.log('BUNDLE_ACTIVE getRecentlyUsedModules callback result ' + JSON.stringify(res[i]));
}
}
});
// 无maNum参数异步方法callback方式
stats.getRecentlyUsedModules((err, res) => {
if (err) {
console.log('BUNDLE_ACTIVE getRecentlyUsedModules callback failed, because: ' + err.code);
} else {
console.log('BUNDLE_ACTIVE getRecentlyUsedModules callback succeeded.');
for (let i = 0; i < res.length; i++) {
console.log('BUNDLE_ACTIVE getRecentlyUsedModules callback number : ' + (i + 1));
console.log('BUNDLE_ACTIVE getRecentlyUsedModules callback result ' + JSON.stringify(res[i]));
}
}
});
```
9. 通过指定起始和结束时间查询所有应用的通知次数,config.json中需要配置权限:ohos.permission.BUNDLE_ACTIVE_INFO。
......@@ -278,23 +178,12 @@ import stats from '@ohos.bundleState';
```js
import stats from '@ohos.bundleState'
// 异步方法promise方式
stats.queryAppNotificationNumber(0, 20000000000000).then(res => {
console.log('BUNDLE_ACTIVE queryAppNotificationNumber promise success.');
console.log('BUNDLE_ACTIVE queryAppNotificationNumber promise result ' + JSON.stringify(res));
}).catch(err => {
console.log('BUNDLE_ACTIVE queryAppNotificationNumber promise failed, because: ' + err.code);
});
// 异步方法callback方式
stats.queryAppNotificationNumber(0, 20000000000000, (err, res) => {
if (err) {
console.log('BUNDLE_ACTIVE queryAppNotificationNumber callback failed, because: ' + err.code);
} else {
console.log('BUNDLE_ACTIVE queryAppNotificationNumber callback success.');
console.log('BUNDLE_ACTIVE queryAppNotificationNumber callback result ' + JSON.stringify(res));
}
});
```
10. 通过指定起始和结束时间查询系统事件(休眠、唤醒、解锁、锁屏)统计信息,config.json中需要配置权限:ohos.permission.BUNDLE_ACTIVE_INFO。
......@@ -309,16 +198,6 @@ import stats from '@ohos.bundleState';
}).catch(err => {
console.log('BUNDLE_ACTIVE queryBundleActiveEventStates promise failed, because: ' + err.code);
});
// 异步方法callback方式
stats.queryBundleActiveEventStates(0, 20000000000000, (err, res) => {
if (err) {
console.log('BUNDLE_ACTIVE queryBundleActiveEventStates callback failed, because: ' + err.code);
} else {
console.log('BUNDLE_ACTIVE queryBundleActiveEventStates callback success.');
console.log('BUNDLE_ACTIVE queryBundleActiveEventStates callback result ' + JSON.stringify(res));
}
});
```
11. 查询(无参)当前调用者应用的使用优先级群组,config.json中不需要配置权限。查询(有参)指定应用的使用优先级群组,config.json中需要配置权限:ohos.permission.BUNDLE_ACTIVE_INFO。
......@@ -333,14 +212,6 @@ import stats from '@ohos.bundleState';
console.log('BUNDLE_ACTIVE queryAppUsagePriorityGroup promise failed. because: ' + err.code);
});
// 无bundleName异步方法callback方式
stats.queryAppUsagePriorityGroup((err, res) => {
if (err) {
console.log('BUNDLE_ACTIVE queryAppUsagePriorityGroup callback failed. because: ' + err.code);
} else {
console.log('BUNDLE_ACTIVE queryAppUsagePriorityGroup callback succeeded. result: ' + JSON.stringify(res));
}
});
let bundleName = "com.ohos.camera";
// 有bundleName异步promise方式
stats.queryAppUsagePriorityGroup(bundleName).then(res => {
......@@ -348,15 +219,6 @@ import stats from '@ohos.bundleState';
}).catch(err => {
console.log('BUNDLE_ACTIVE QueryPackageGroup promise failed. because: ' + err.code);
});
// 有bundleName异步方法callback方式
stats.queryAppUsagePriorityGroup(bundleName, (err, res) => {
if (err) {
console.log('BUNDLE_ACTIVE QueryPackageGroup callback failed. because: ' + err.code);
} else {
console.log('BUNDLE_ACTIVE QueryPackageGroup callback succeeded. result: ' + JSON.stringify(res));
}
});
```
11. 给应用名是bundleName的应用分组设置成newGroup,返回设置结果是否成功
......@@ -364,20 +226,11 @@ import stats from '@ohos.bundleState';
```javascript
import stats from '@ohos.bundleState'
// 异步方法promise
stats.setBundleGroup(this.bundleName, this.newGroup).then(() => {
console.log('BUNDLE_ACTIVE SetBundleGroup promise succeeded.');
}).catch( err => {
console.log('BUNDLE_ACTIVE SetBundleGroup promise failed. because: ' + err.code);
});
// 异步方法callback
stats.setBundleGroup(this.bundleName, this.newGroup, (err) => {
if (err) {
console.log('BUNDLE_ACTIVE SetBundleGroup callback failed. because: ' + err.code);
} else {
console.log('BUNDLE_ACTIVE SetBundleGroup callback succeeded.');
}
});
```
12. 注册应用分组变化监听回调,返回注册是否成功,当应用分组发生变化时,会给所有已注册的监听者返回回调信息
......@@ -399,22 +252,6 @@ import stats from '@ohos.bundleState';
}).catch(err => {
console.log('BUNDLE_ACTIVE RegisterGroupCallBack promise failed. because: ' + err.code);
});
// 异步方法callback形式
let onBundleGroupChanged = (err,res) => {
console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack callback success.');
console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack result‘s oldGroup is : ' + res.oldGroup);
console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack result‘s newGroup is : ' + res.newGroup);
console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack result‘s changeReason is : ' + res.newGroup);
console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack result‘s userId is : ' + res.userId);
console.log('BUNDLE_ACTIVE onBundleGroupChanged RegisterGroupCallBack result‘s bundleName is : ' + res.bundleName);
};
stats.registerGroupCallBack(onBundleGroupChanged, (err) => {
if (err) {
console.log('BUNDLE_ACTIVE RegisterGroupCallBack callback failed, because: ' + err.code);
} else {
console.log('BUNDLE_ACTIVE RegisterGroupCallBack callback success.');
}
});
```
13. 解除应用分组监听回调
......@@ -428,15 +265,8 @@ import stats from '@ohos.bundleState';
}).catch(err => {
console.log('BUNDLE_ACTIVE UnRegisterGroupCallBack promise failed. because: ' + err.code);
});
// callback
stats.unRegisterGroupCallBack((err) => {
if (err) {
console.log('BUNDLE_ACTIVE UnRegisterGroupCallBack callback failed, because: ' + err.code);
} else {
console.log('BUNDLE_ACTIVE UnRegisterGroupCallBack callback success.');
}
});
```
## 相关实例
针对设备使用信息统计,有以下相关实例可供参考:
- [`DeviceUsageStatistics`:设备使用信息统计(ArkTS)(API8)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/device/DeviceUsageStatistics)
......
......@@ -2,12 +2,11 @@
- 后台任务
- [后台任务概述](background-task-overview.md)
- [后台任务开发指导](background-task-dev-guide.md)
- 延迟任务调度
- [延迟任务调度概述](work-scheduler-overview.md)
- [延迟任务调度开发指导](work-scheduler-dev-guide.md)
- [短时任务开发指导](transient-task-dev-guide.md)
- [长时任务开发指导](continuous-task-dev-guide.md)
- [延迟任务开发指导](work-scheduler-dev-guide.md)
- [申请能效资源开发指导](efficiency-resources-apply-dev-guide.md)
- 后台代理提醒
- [后台代理提醒开发概述](background-agent-scheduled-reminder-overview.md)
- [后台代理提醒开发指导](background-agent-scheduled-reminder-guide.md)
\ No newline at end of file
- [后台代理提醒开发指导](background-agent-scheduled-reminder-guide.md)
......@@ -24,147 +24,155 @@ reminderAgent:封装了发布、取消提醒类通知的方法。
## 开发步骤
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> **说明:**
>
> 1. 应用需要配置权限:ohos.permission.PUBLISH_AGENT_REMINDER。
>
> 2. 应用需要申请通知弹窗:[Notification.requestEnableNotification](../reference/apis/js-apis-notification.md#notificationrequestenablenotification8)。
1. 定义一个提醒代理。
倒计时实例定义:
```js
import reminderAgent from '@ohos.reminderAgent';
import notification from '@ohos.notification';
export default {
// eTS工程:
let timer : reminderAgent.ReminderRequestTimer = {
reminderType: reminderAgent.ReminderType.REMINDER_TYPE_TIMER,
triggerTimeInSeconds: 10,
actionButton: [
{
title: "close",
type: reminderAgent.ActionButtonType.ACTION_BUTTON_TYPE_CLOSE
}
],
wantAgent: {
pkgName: "com.example.device",
abilityName: "com.example.device.MainAbility"
},
maxScreenWantAgent: {
pkgName: "com.example.device",
abilityName: "com.example.device.MainAbility"
},
title: "this is title",
content: "this is content",
expiredContent: "this reminder has expired",
notificationId: 100,
slotType: notification.SlotType.SOCIAL_COMMUNICATION
}
}
```
日历实例定义:
```js
// eTS工程:
let calendar : reminderAgent.ReminderRequestCalendar = {
reminderType: reminderAgent.ReminderType.REMINDER_TYPE_CALENDAR,
dateTime: {
year: 2050,
month: 7,
day: 30,
hour: 11,
minute: 14,
second: 30
},
repeatMonths: [1],
repeatDays: [1],
actionButton: [
{
title: "close",
type: reminderAgent.ActionButtonType.ACTION_BUTTON_TYPE_CLOSE
},
{
title: "snooze",
type: reminderAgent.ActionButtonType.ACTION_BUTTON_TYPE_SNOOZE
},
],
wantAgent: {
pkgName: "com.example.device",
abilityName: "com.example.device.MainAbility"
},
maxScreenWantAgent: {
pkgName: "com.example.device",
abilityName: "com.example.device.MainAbility"
},
ringDuration: 5,
snoozeTimes: 2,
timeInterval: 5,
title: "this is title",
content: "this is content",
expiredContent: "this reminder has expired",
snoozeContent: "remind later",
notificationId: 100,
slotType: notification.SlotType.SOCIAL_COMMUNICATION
}
```
闹钟实例定义:
```js
// eTS工程:
let alarm : reminderAgent.ReminderRequestAlarm = {
reminderType: reminderAgent.ReminderType.REMINDER_TYPE_ALARM,
> 只有用户授权后,提醒代理的功能才能使用。
1、定义目标提醒代理。
2、发布相应的提醒代理。
```ts
import reminderAgent from '@ohos.reminderAgent';
import notification from '@ohos.notification';
// 倒计时实例定义:
let timer : reminderAgent.ReminderRequestTimer = {
reminderType: reminderAgent.ReminderType.REMINDER_TYPE_TIMER,
triggerTimeInSeconds: 10,
actionButton: [
{
title: "close",
type: reminderAgent.ActionButtonType.ACTION_BUTTON_TYPE_CLOSE
}
],
wantAgent: {
pkgName: "com.example.device",
abilityName: "com.example.device.MainAbility"
},
maxScreenWantAgent: {
pkgName: "com.example.device",
abilityName: "com.example.device.MainAbility"
},
title: "this is title",
content: "this is content",
expiredContent: "this reminder has expired",
notificationId: 100,
slotType: notification.SlotType.SOCIAL_COMMUNICATION
}
// 日历实例定义:
let calendar : reminderAgent.ReminderRequestCalendar = {
reminderType: reminderAgent.ReminderType.REMINDER_TYPE_CALENDAR,
dateTime: {
year: 2050,
month: 7,
day: 30,
hour: 11,
minute: 14,
daysOfWeek: [0],
actionButton: [
{
title: "close",
type: reminderAgent.ActionButtonType.ACTION_BUTTON_TYPE_CLOSE
},
{
title: "snooze",
type: reminderAgent.ActionButtonType.ACTION_BUTTON_TYPE_SNOOZE
},
],
wantAgent: {
pkgName: "com.example.device",
abilityName: "com.example.device.MainAbility"
second: 30
},
repeatMonths: [1],
repeatDays: [1],
actionButton: [
{
title: "close",
type: reminderAgent.ActionButtonType.ACTION_BUTTON_TYPE_CLOSE
},
{
title: "snooze",
type: reminderAgent.ActionButtonType.ACTION_BUTTON_TYPE_SNOOZE
},
],
wantAgent: {
pkgName: "com.example.device",
abilityName: "com.example.device.MainAbility"
},
maxScreenWantAgent: {
pkgName: "com.example.device",
abilityName: "com.example.device.MainAbility"
},
ringDuration: 5,
snoozeTimes: 2,
timeInterval: 5,
title: "this is title",
content: "this is content",
expiredContent: "this reminder has expired",
snoozeContent: "remind later",
notificationId: 100,
slotType: notification.SlotType.SOCIAL_COMMUNICATION
}
// 闹钟实例定义:
let alarm : reminderAgent.ReminderRequestAlarm = {
reminderType: reminderAgent.ReminderType.REMINDER_TYPE_ALARM,
hour: 11,
minute: 14,
daysOfWeek: [0],
actionButton: [
{
title: "close",
type: reminderAgent.ActionButtonType.ACTION_BUTTON_TYPE_CLOSE
},
maxScreenWantAgent: {
pkgName: "com.example.device",
abilityName: "com.example.device.MainAbility"
{
title: "snooze",
type: reminderAgent.ActionButtonType.ACTION_BUTTON_TYPE_SNOOZE
},
ringDuration: 5,
snoozeTimes: 2,
timeInterval: 5,
title: "this is title",
content: "this is content",
expiredContent: "this reminder has expired",
snoozeContent: "remind later",
notificationId: 100,
slotType: notification.SlotType.SOCIAL_COMMUNICATION
],
wantAgent: {
pkgName: "com.example.device",
abilityName: "com.example.device.MainAbility"
},
maxScreenWantAgent: {
pkgName: "com.example.device",
abilityName: "com.example.device.MainAbility"
},
ringDuration: 5,
snoozeTimes: 2,
timeInterval: 5,
title: "this is title",
content: "this is content",
expiredContent: "this reminder has expired",
snoozeContent: "remind later",
notificationId: 100,
slotType: notification.SlotType.SOCIAL_COMMUNICATION
}
@Entry
@Component
struct Index {
@State message: string = 'test'
publishReminder() {
reminderAgent.publishReminder(timer, (err, reminderId) => {
console.log("callback, reminderId = " + reminderId);
});
}
build() {
Row() {
Column() {
Text("Index")
.fontSize(50)
.fontWeight(FontWeight.Bold)
Button() { Text('倒计时提醒代理').fontSize(25).fontWeight(FontWeight.Bold) }.type(ButtonType.Capsule)
.margin({ top: 10 }).backgroundColor('#0D9FFB').width(250).height(40)
.onClick(() => {
// 示例通过按钮控制提醒代理的发布
this.publishReminder();
})
}
.width('100%')
}
```
2. 发布倒计时提醒。
```js
startTimer() {
reminderAgent.publishReminder(this.timer, (err, reminderId) =>{
this.printInfo(JSON.stringify(err));
this.printInfo("reminderId:" + reminderId);
});
}
```
HML页面:
```html
<div class="container">
<button type="text" value="publishReminder" onclick="startTimer"></button>
</div>
```
.height('100%')
}
}
```
## 相关实例
......
# 后台代理提醒概述
开发者在应用开发时,可以调用后台代理提醒类ReminderRequest去创建定时提醒,包括倒计时、日历、闹钟三种提醒类型。使用后台代理提醒能力后,应用可以被冻结或退出,计时和弹出提醒的功能将被后台系统服务代理。
OpenHarmony设计了相关的后台活动规范。三方应用退后台后如果没有执行相关的后台任务,会被挂起。而对于某些应用,可能需要在某些指定的时刻,处理一些工作。如购物类应用,可能需要在某些时间点,提醒用户有抢购活动可以参加。此类功能通常的实现是应用使用定时器,在时间达到后,由系统拉起应用,执行相关的任务。但是给应用开放了定时器的功能,可能会造成这个机制被滥用,导致后台被挂起的应用频繁地用定时器唤醒。为了避免恶意的后台活动,同时满足应用的业务诉求,设计了后台代理提醒功能。
开发者在应用开发时,使用后台代理提醒能力后,应用可以被挂起或退出,计时和弹出提醒的功能将被后台系统服务代理。避免的应用被频繁唤醒的问题,有助于降低功耗。
## 提醒实例类型
- **倒计时类型**:基于倒计时的提醒功能,适用于短时的计时提醒业务。
- **日历类型**:基于日历的提醒功能,适用于较长时间的提醒业务。
- **闹钟类型**:基于时钟的提醒功能,应用可以使用此功能,实现闹钟相关的业务。
# 后台任务概述
后台应用频繁活动,会造成用户设备耗电快、卡顿等现象。因此,为了支撑性能、功耗诉求,系统仅允许应用在后台执行规范内的活动,规范外的活动默认会被挂起,当资源不足时会被回收。同时,应用可以申请能效资源,保证自己在一段时间内不会被挂起,或者在挂起状态能够正常使用一些资源,例如公共事件、计时器等。
后台应用频繁活动,会造成用户设备耗电快、卡顿等现象。因此,为了支撑性能、功耗诉求,系统仅允许应用在后台执行规范内的活动,规范外的活动默认会被挂起,当资源不足时会被回收。
针对应用或业务模块处于后台(无可见界面)时,有需要继续执行或者后续执行的业务,可基于业务类型,申请[短时任务](#短时任务)延迟挂起或者[长时任务](#长时任务)避免进入挂起状态;使用[延迟调度任务](#延迟任务),执行对实时性要求不高的任务;同时针对特权应用,如果需要更加灵活的配置,可以申请[能效资源](#申请能效资源)
## 后台任务类型
本文描述的后台任务特指应用或业务模块处于后台(无可见界面)时,有需要继续执行或者后续执行的业务。OpenHarmony将后台任务分为三种类型,并执行不同的处理
OpenHarmony将后台任务分为四种类型,并提供了一个资源申请的扩展功能
**1. 无后台业务** :应用或业务模块退到后台后,无任务需要处理。
**无后台业务** :应用或业务模块退到后台后,无任务需要处理。
**2. 短时任务** :应用或业务模块退到后台后,如果有紧急不可推迟且短时间能完成的任务,如应用退后台要进行数据压缩,不可中断,则使用短时任务申请延迟进入挂起(Suspend)状态。
**短时任务** :应用或业务模块退到后台后,如果有紧急不可推迟且短时间能完成的任务,如应用退后台要进行数据压缩,不可中断,则使用短时任务申请延迟进入挂起(Suspend)状态。
**3. 长时任务** :如果是用户发起的可感知业务需要长时间后台运行,如后台播放音乐、导航、设备连接、VoIP等,则使用长时任务避免进入挂起(Suspend)状态。
**长时任务** :如果是用户发起的可感知业务需要长时间后台运行,如后台播放音乐、导航、设备连接、VoIP等,则使用长时任务避免进入挂起(Suspend)状态。
**4. 能效资源** :能效资源包括CPU资源、WORK_SCHEDULER资源、软件资源(COMMON_EVENT, TIMER)、硬件资源(GPS, BLUETOOTH)。如果应用或者进程申请了能效资源,那么根据能效资源的类型会拥有相应的特权,例如申请了CPU资源的可以不被挂起,申请了WORK_SCHEDULER后延时任务可以拥有更长的执行时间
**延迟任务** :延迟任务调度给应用提供一个机制,允许应用根据系统安排,在系统空闲时执行实时性不高的任务。当满足设定条件的时候,任务会被放入待调度队列,当系统空闲时调度该任务
**能效资源** :能效资源包括CPU资源、WORK_SCHEDULER资源、软件资源(COMMON_EVENT, TIMER)、硬件资源(GPS, BLUETOOTH)。如果应用或者进程申请了能效资源,那么根据能效资源的类型会拥有相应的特权,例如申请了CPU资源的可以不被挂起,申请了WORK_SCHEDULER后延时任务可以拥有更长的执行时间。
## 最佳后台任务选择
![后台任务选择](public_sys-resources/bgtask_choice.png)
## 短时任务
退到后台的应用有不可中断且短时间能完成的任务时,可以使用短时任务机制。该机制允许应用在后台短时间内完成任务,保障应用业务运行不受后台生命周期管理的影响。
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> **说明:**
> 短时任务仅针对应用的临时任务提供资源使用生命周期保障,限制单次最大使用时长为3分钟,全天使用配额默认为10分钟(具体时长系统根据应用场景和系统状态智能调整)。
......@@ -63,9 +69,44 @@ OpenHarmony提供了九种后台模式,供需要在后台做长时任务的业
- 长时任务是为了真正在后台长时间执行某个任务,如果一个应用申请了长时任务,但在实际运行过程中,并未真正运行或执行此类任务时,也会被系统检测到并被挂起(Suspend)。
- 一个Ability同一时刻只能申请运行一个长时任务。
## 能效资源申请
能效资源可以分为四种,CPU资源,WORK_SCHEDULER资源,软件资源(COMMON_EVENT,TIMER),硬件资源(GPS,BLOOTOOTH,AUDIO)。
应用或进程申请能效资源后能够获得相应特权,例如:申请CPU资源后可以不被挂起;申请WORK_SCHEDULER资源后不受延迟任务执行频率约束,且任务执行时间增加;申请软件、硬件资源后,相关资源在挂起状态下不被代理。
## 延迟任务
延迟任务调度给应用提供一个机制,允许应用根据系统安排,在系统空闲时执行实时性要求不高的任务,比如设备空闲时候做一次数据学习等场景。当应用申请延迟任务的时候,任务会被放入待调度队列,系统会根据当前状态,如内存、功耗、温度等统一决策最优的调度时机。同时支持任务的持久化,应用退出或者设备重启,设置的任务同样能够被触发。
### 延迟任务调度约束
延迟调度任务的使用需要遵从如下约束和规则:
- **超时**:系统会设置超时机制,延迟任务回调只允许运行一段时间,超时之后,系统会主动停止。默认的超时限制为2分钟,对于系统应用,可以通过[申请能效资源](efficiency-resources-apply-dev-guide.md)获取更长的执行时间(充电状态20分钟,非充电状态10分钟)。
- **执行频率**:系统会根据应用的活跃度对延迟任务做分级管控,限制延迟任务调度的执行频率。对于通过能效资源接口申请了WORK_SCHEDULER资源的应用,在资源的有效期内,它的延迟任务执行频率不受限制。
| 应用分组 | 延迟任务执行频率约束 |
| --------------------|------------------------- |
| 活跃 | 最小间隔2小时 |
| 每日使用 | 最小间隔4小时 |
| 经常使用 | 最小间隔24小时 |
| 不经常使用 | 最小间隔48小时 |
| 受限分组 | 禁止 |
| 未使用分组 | 禁止 |
| [能效资源豁免分组](../reference/apis/js-apis-backgroundTaskManager.md#resourcetype9) | 执行频率不受限制 |
- **WorkInfo设置参数约束**
- workId、bundleName、abilityName为必填项,bundleName必须填本应用,否则校验失败。
- 至少要设置一个满足的条件。
- 重复任务时间间隔至少20分钟,当设置重复任务时间间隔时,必须设置始终重复和重复次数中的一个。
- 携带参数信息支持number、string、bool三种类型。
## 申请能效资源
能效资源可以分为四种:CPU资源,WORK_SCHEDULER资源,软件资源(COMMON_EVENT,TIMER),硬件资源(GPS,BLUETOOTH,AUDIO)。
应用或进程申请能效资源后能够获得相应特权:
* 申请CPU资源后可以不被挂起,直到任务完成。
* 申请WORK_SCHEDULER资源后不受延迟任务执行频率约束,且任务执行时间增加
* 申请COMMON_EVENT资源后,应用在后台处于挂起状态时,仍然能够接收到系统公共事件,申请TIMER资源后,应用能够使用定时器执行精确定时任务、
* 申请硬件资源后,应用在后台被挂起后,依然能够被相关服务唤醒,执行相应的任务。
**表1** 能效资源种类
......@@ -84,3 +125,4 @@ OpenHarmony提供了九种后台模式,供需要在后台做长时任务的业
- 能效资源申请或者释放可以由进程或者应用发起,由应用发起的资源释放会释放属于它的同类型的所有资源,包括进程申请的资源。例如应用申请了CPU资源,进程申请了CPU和WORK_SCHEDULER资源,当应用释放CPU资源的时候,会将进程的CPU资源一同释放,同时不同类型的WORK_SCHEDULER资源不受影响。由进程发起的资源释放对应用申请的资源没有影响,例如当应用和进程同时申请了CPU,进程发起了CPU资源释放,应用的CPU资源不会被释放。
- 同时申请同一类持久资源和非持久资源,持久资源会覆盖非持久资源,在超时时不会释放资源。例如应用首先申请了10s的CPU资源,然后在第5s的时候申请了持久的CPU资源,那么资源会变成持久的,非持久的CPU资源记录会被持久化的CPU资源记录覆盖,到了第10s的时候资源不会被释放,如果在第8s的时候提前释放了资源,那么会将CPU资源释放,无法单独释放其中非持久的或者持久的CPU资源。
- WORK_SCHEDULER资源只能由应用申请和释放,不能由进程申请和释放。
- 需要使用能效资源的应用,需要向应用中心提出申请,获取相应的特权。
# 后台任务开发指导
## 场景介绍
应用或业务模块处于后台(无可见界面)时,如果有需要继续执行或者后续执行的业务,可基于业务类型,申请短时任务延迟挂起(Suspend)或者长时任务避免进入挂起状态。如果应用需要更加灵活的配置,可以申请能效资源。常见的使用能效资源的场景有:1.应用保证自己在一个时间段内不被挂起,直到任务完成;2.应用处于挂起状态时仍然需要系统的资源,例如闹钟需要计时器资源;3.延时任务需要不受到执行频率的限制,并且拥有更长的执行时间。
在挂起时如果需要单独的某种资源不被代理或者需要更长的延时任务执行时间,可以申请所需的能效资源。
## 短时任务
### 接口说明
**表1** 短时任务主要接口
| 接口名 | 描述 |
| ---------------------------------------- | ---------------------------------------- |
| requestSuspendDelay(reason:&nbsp;string,&nbsp;callback:&nbsp;Callback&lt;void&gt;):&nbsp;[DelaySuspendInfo](../reference/apis/js-apis-backgroundTaskManager.md#delaysuspendinfo) | 后台应用申请延迟挂起。<br/>延迟挂起时间一般情况下默认值为180000,低电量时默认值为60000。 |
| getRemainingDelayTime(requestId:&nbsp;number):&nbsp;Promise&lt;number&gt; | 获取应用程序进入挂起状态前的剩余时间。<br/>使用Promise形式返回。 |
| cancelSuspendDelay(requestId:&nbsp;number):&nbsp;void | 取消延迟挂起。 |
### 开发步骤
1. 申请延迟挂起
```js
import backgroundTaskManager from '@ohos.backgroundTaskManager';
let myReason = 'test requestSuspendDelay';
let delayInfo = backgroundTaskManager.requestSuspendDelay(myReason, () => {
console.info("Request suspension delay will time out.");
});
var id = delayInfo.requestId;
console.info("requestId is: " + id);
```
2. 获取进入挂起前的剩余时间
```js
backgroundTaskManager.getRemainingDelayTime(id).then( res => {
console.log('promise => Operation getRemainingDelayTime succeeded. Data: ' + JSON.stringify(res));
}).catch( err => {
console.log('promise => Operation getRemainingDelayTime failed. Cause: ' + err.code);
});
```
3. 取消延迟挂起
```js
backgroundTaskManager.cancelSuspendDelay(id);
```
### 开发实例
## 长时任务
```js
import backgroundTaskManager from '@ohos.backgroundTaskManager';
let myReason = 'test requestSuspendDelay';
// 申请延迟挂起
let delayInfo = backgroundTaskManager.requestSuspendDelay(myReason, () => {
console.info("Request suspension delay will time out.");
});
// 打印延迟挂起信息
var id = delayInfo.requestId;
var time = delayInfo.actualDelayTime;
console.info("The requestId is: " + id);
console.info("The actualDelayTime is: " + time);
// 获取应用程序进入挂起状态前的剩余时间
backgroundTaskManager.getRemainingDelayTime(id).then( res => {
console.log('promise => Operation getRemainingDelayTime succeeded. Data: ' + JSON.stringify(res));
}).catch( err => {
console.log('promise => Operation getRemainingDelayTime failed. Cause: ' + err.code);
});
// 取消延迟挂起
backgroundTaskManager.cancelSuspendDelay(id);
```
### 场景说明
## 长时任务
如果应用需要在后台长时间执行用户可感知的任务,如后台播放音乐、导航、设备连接、VoIP等,则使用长时任务避免进入挂起(Suspend)状态。
长时任务在后台执行没有时间限制。为了避免该机制被滥用,系统只允许申请有限个数的长时任务类型,同时会有相应的通知提示与长时任务相关联,使用户可感知,并且系统会添加相应的校验机制,确保应用是的确在执行相应的长时任务。
### 权限
......@@ -120,146 +40,35 @@ ohos.permission.KEEP_BACKGROUND_RUNNING
基于FA模型:
1. 新建Api Version 8的工程后,在工程目录中右键选择“new” -> “Ability” -> “Service Ability” 快速创建Service Ability组件。并在config.json文件中配置长时任务权限、后台模式类型,其中Ability类型为“service”。
```
"module": {
"package": "com.example.myapplication",
"abilities": [
{
"backgroundModes": [
"dataTransfer",
"location"
], // 后台模式类型
"type": "service" // ability类型为service
}
],
"reqPermissions": [
{
"name": "ohos.permission.KEEP_BACKGROUND_RUNNING" // 长时任务权限
}
]
}
```
2. 申请长时任务。
```js
import backgroundTaskManager from '@ohos.backgroundTaskManager';
import featureAbility from '@ohos.ability.featureAbility';
import wantAgent from '@ohos.wantAgent';
let wantAgentInfo = {
wants: [
{
bundleName: "com.example.myapplication",
abilityName: "com.example.myapplication.MainAbility"
}
],
operationType: wantAgent.OperationType.START_ABILITY,
requestCode: 0,
wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG]
};
// 通过wantAgent模块的getWantAgent方法获取WantAgent对象
wantAgent.getWantAgent(wantAgentInfo).then((wantAgentObj) => {
backgroundTaskManager.startBackgroundRunning(featureAbility.getContext(),
backgroundTaskManager.BackgroundMode.DATA_TRANSFER, wantAgentObj).then(() => {
console.info("Operation startBackgroundRunning succeeded");
}).catch((err) => {
console.error("Operation startBackgroundRunning failed Cause: " + err);
});
});
```
3. 停止长时任务。
```js
import backgroundTaskManager from '@ohos.backgroundTaskManager';
import featureAbility from '@ohos.ability.featureAbility';
backgroundTaskManager.stopBackgroundRunning(featureAbility.getContext()).then(() => {
console.info("Operation stopBackgroundRunning succeeded");
}).catch((err) => {
console.error("Operation stopBackgroundRunning failed Cause: " + err);
});
基于FA的Service Ability使用,参考[ServiceAbility开发指导](../ability/fa-serviceability.md)
```
当不需要与后台执行的长时任务交互时,可以采用startAbility()方法启动Service Ability。并在Service Ability的onStart回调方法中,调用长时任务的申请接口,声明此服务需要在后台长时运行。当任务执行完,再调用长时任务取消接口,及时释放资源。
基于Stage模型:
当需要与后台执行的长时任务交互时(如播放音乐等)。可以采用connectAbility()方法启动并连接Service Ability。在获取到服务的代理对象后,与服务进行通信,控制长时任务的申请和取消。
1. 新建Api Version 9的工程后,在工程目录中右键选择“New” -> “Ability” 快速创建Ability组件。并在module.json5文件中配置长时任务权限、后台模式类型
1、新建Api Version 8的工程后,在工程目录中右键选择“new” -> “Ability” -> “Service Ability” 快速创建Service Ability组件。并在config.json文件中配置长时任务权限、后台模式类型,其中Ability类型为“service”
```
"module": {
"abilities": [
```
"module": {
"package": "com.example.myapplication",
"abilities": [
{
"backgroundModes": [
"backgroundModes": [
"dataTransfer",
"location"
], // 后台模式类型
], // 后台模式类型
"type": "service" // ability类型为service
}
],
"requestPermissions": [
],
"reqPermissions": [
{
"name": "ohos.permission.KEEP_BACKGROUND_RUNNING" // 长时任务权限
"name": "ohos.permission.KEEP_BACKGROUND_RUNNING" // 长时任务权限
}
]
}
```
2. 申请长时任务。
```ts
import backgroundTaskManager from '@ohos.backgroundTaskManager';
import wantAgent from '@ohos.wantAgent';
let wantAgentInfo = {
wants: [
{
bundleName: "com.example.myapplication",
abilityName: "com.example.myapplication.MainAbility"
}
],
operationType: wantAgent.OperationType.START_ABILITY,
requestCode: 0,
wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG]
};
// 通过wantAgent模块的getWantAgent方法获取WantAgent对象
wantAgent.getWantAgent(wantAgentInfo).then((wantAgentObj) => {
backgroundTaskManager.startBackgroundRunning(this.context,
backgroundTaskManager.BackgroundMode.DATA_TRANSFER, wantAgentObj).then(() => {
console.info("Operation startBackgroundRunning succeeded");
}).catch((err) => {
console.error("Operation startBackgroundRunning failed Cause: " + err);
});
});
```
3. 停止长时任务。
```ts
import backgroundTaskManager from '@ohos.backgroundTaskManager';
backgroundTaskManager.stopBackgroundRunning(this.context).then(() => {
console.info("Operation stopBackgroundRunning succeeded");
}).catch((err) => {
console.error("Operation stopBackgroundRunning failed Cause: " + err);
});
```
### 开发实例
基于FA模型:
基于FA的Service Ability使用,参考[ServiceAbility开发指导](../ability/fa-serviceability.md)
当不需要与后台执行的长时任务交互时,可以采用startAbility()方法启动Service Ability。并在Service Ability的onStart回调方法中,调用长时任务的申请接口,声明此服务需要在后台长时运行。当任务执行完,再调用长时任务取消接口,及时释放资源。
]
}
```
当需要与后台执行的长时任务交互时(如播放音乐等)。可以采用connectAbility()方法启动并连接Service Ability。在获取到服务的代理对象后,与服务进行通信,控制长时任务的申请和取消
2、在Service Ability调用长时任务的申请和取消接口
```js
import backgroundTaskManager from '@ohos.backgroundTaskManager';
......@@ -367,13 +176,117 @@ export default {
基于Stage模型:
Stage模型的相关信息参考[Stage模型综述](../ability/stage-brief.md)
当应用需要在后台执行长时任务时,可以通过Call的方式在后台创建并运行Ability。使用方式参考[Call调用开发指导](../ability/stage-call.md)
1、新建Api Version 9的工程后,在工程目录中右键选择“New” -> “Ability” 快速创建Ability组件。并在module.json5文件中配置长时任务权限、后台模式类型。
```
"module": {
"abilities": [
{
"backgroundModes": [
"dataTransfer",
"location"
], // 后台模式类型
}
],
"requestPermissions": [
{
"name": "ohos.permission.KEEP_BACKGROUND_RUNNING" // 长时任务权限
}
]
}
```
2、在应用内执行长时任务时,由于元能力启动管控规则限制,不支持同应用通过startAbilityByCall的形式在后台创建并运行Ability。可以直接在page中,执行相应的代码。Stage模型的Ability使用参考[Ability开发指导](../ability/stage-ability.md)
```ts
import wantAgent from '@ohos.wantAgent';
import backgroundTaskManager from '@ohos.backgroundTaskManager';
@Entry
@Component
struct Index {
@State message: string = 'test'
// 通过getContext方法,来获取page所在的Ability上下文。
private context: any = getContext(this)
startContinuousTask() {
let wantAgentInfo = {
// 点击通知后,将要执行的动作列表
wants: [
{
bundleName: "com.example.myapplication",
abilityName: "com.example.myapplication.MainAbility",
}
],
// 点击通知后,动作类型
operationType: wantAgent.OperationType.START_ABILITY,
// 使用者自定义的一个私有值
requestCode: 0,
// 点击通知后,动作执行属性
wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG]
};
// 通过wantAgent模块的getWantAgent方法获取WantAgent对象
wantAgent.getWantAgent(wantAgentInfo).then((wantAgentObj) => {
backgroundTaskManager.startBackgroundRunning(this.context,
backgroundTaskManager.BackgroundMode.DATA_TRANSFER, wantAgentObj).then(() => {
console.info("Operation startBackgroundRunning succeeded");
}).catch((err) => {
console.error("Operation startBackgroundRunning failed Cause: " + err);
});
});
}
stopContinuousTask() {
backgroundTaskManager.stopBackgroundRunning(this.context).then(() => {
console.info("Operation stopBackgroundRunning succeeded");
}).catch((err) => {
console.error("Operation stopBackgroundRunning failed Cause: " + err);
});
}
build() {
Row() {
Column() {
Text("Index")
.fontSize(50)
.fontWeight(FontWeight.Bold)
Button() { Text('申请长时任务').fontSize(25).fontWeight(FontWeight.Bold) }.type(ButtonType.Capsule)
.margin({ top: 10 }).backgroundColor('#0D9FFB').width(250).height(40)
.onClick(() => {
// 通过按钮申请长时任务
this.startContinuousTask();
// 此处执行具体的长时任务逻辑,如放音等。
})
Button() { Text('取消长时任务').fontSize(25).fontWeight(FontWeight.Bold) }.type(ButtonType.Capsule)
.margin({ top: 10 }).backgroundColor('#0D9FFB').width(250).height(40)
.onClick(() => {
// 此处结束具体的长时任务的执行
// 通过按钮取消长时任务
this.stopContinuousTask();
})
}
.width('100%')
}
.height('100%')
}
}
```
3、当需要跨设备或者跨应用在后台执行长时任务时,可以通过Call的方式在后台创建并运行Ability。使用方式参考[Call调用开发指导](../ability/stage-call.md)
```ts
import Ability from '@ohos.application.Ability'
import backgroundTaskManager from '@ohos.backgroundTaskManager';
import wantAgent from '@ohos.wantAgent';
const MSG_SEND_METHOD: string = 'CallSendMsg'
let mContext = null;
function startContinuousTask() {
......@@ -382,7 +295,7 @@ function startContinuousTask() {
wants: [
{
bundleName: "com.example.myapplication",
abilityName: "com.example.myapplication.MainAbility"
abilityName: "com.example.myapplication.MainAbility",
}
],
// 点击通知后,动作类型
......@@ -436,15 +349,16 @@ class MySequenceable {
function sendMsgCallback(data) {
console.info('BgTaskAbility funcCallBack is called ' + data)
let receivedData = new Mysequenceable(0, "")
let receivedData = new MySequenceable(0, "")
data.readSequenceable(receivedData)
console.info(`receiveData[${receivedData.num}, ${receivedData.str}]`)
// 可以根据Caller端发送的序列化数据的str值,执行不同的方法。
if (receivedData.str === 'start_bgtask') {
startContinuousTask()
} else if (receivedData.str === 'stop_bgtask') {
stopContinuousTask();
}
return new Mysequenceable(10, "Callee test");
return new MySequenceable(10, "Callee test");
}
export default class BgTaskAbility extends Ability {
......@@ -467,7 +381,7 @@ export default class BgTaskAbility extends Ability {
onWindowStageCreate(windowStage) {
console.info("[Demo] BgTaskAbility onWindowStageCreate")
windowStage.loadContent("pages/second").then((data)=> {
windowStage.loadContent("pages/index").then((data)=> {
console.info(`load content succeed with data ${JSON.stringify(data)}`)
}).catch((error)=>{
console.error(`load content failed with error ${JSON.stringify(error)}`)
......@@ -488,93 +402,6 @@ export default class BgTaskAbility extends Ability {
};
```
## 能效资源申请
### 接口说明
**表1** 能效资源申请主要接口
| 接口名 | 描述 |
| ---------------------------------------- | ---------------------------------------- |
| applyEfficiencyResources(request: [EfficiencyResourcesRequest](../reference/apis/js-apis-backgroundTaskManager.md#efficiencyresourcesrequest9)): boolean | 申请能效资源。 |
| resetAllEfficiencyResources():void | 释放申请的能效资源。 |
### 开发步骤
1. 申请能效资源
```js
import backgroundTaskManager from '@ohos.backgroundTaskManager';
let request = {
resourceTypes: backgroundTaskManager.ResourceType.CPU,
isApply: true,
timeOut: 0,
reason: "apply",
isPersist: true,
isProcess: true,
};
let res = backgroundTaskManager.applyEfficiencyResources(request);
console.info("the result of request is: " + res);
```
2. 释放申请的部分资源
```js
import backgroundTaskManager from '@ohos.backgroundTaskManager';
let request = {
resourceTypes: backgroundTaskManager.ResourceType.CPU,
isApply: false,
timeOut: 0,
reason: "reset",
};
let res = backgroundTaskManager.applyEfficiencyResources(request);
console.info("the result of request is: " + res);
```
3. 释放申请的所有资源
```js
import backgroundTaskManager from '@ohos.backgroundTaskManager';
backgroundTaskManager.backgroundTaskManager.resetAllEfficiencyResources();
```
### 开发实例
```js
import backgroundTaskManager from '@ohos.backgroundTaskManager';
// 申请能效资源
let request = {
resourceTypes: backgroundTaskManager.ResourceType.COMMON_EVENT |
backgroundTaskManager.ResourceType.TIMER,
isApply: true,
timeOut: 0,
reason: "apply",
isPersist: true,
isProcess: true,
};
let res = backgroundTaskManager.applyEfficiencyResources(request);
console.info("the result of request is: " + res);
// 释放部分资源
request = {
resourceTypes: backgroundTaskManager.ResourceType.COMMON_EVENT,
isApply: false,
timeOut: 0,
reason: "reset",
};
res = backgroundTaskManager.applyEfficiencyResources(request);
console.info("the result of request is: " + res);
// 释放全部资源
backgroundTaskManager.backgroundTaskManager.resetAllEfficiencyResources();
```
## 相关实例
基于后台任务管理,有以下相关实例可供参考:
......
## 申请能效资源
### 场景说明
在实际的系统中,存在一些重要性高的系统应用,虽然此类应用相比普通应用具有一定的特权,但为了进一步平衡系统的功耗开销,这些应用同样需要支持在后台可被挂起。但对于系统特权应用,为了避免挂起后重要功能受到影响,提供了独立的能效资源申请接口,使这些特权应用可以在后台执行一些特殊的任务和使用特定的系统资源,例如在被挂起期间如果仍然希望能够收到系统公共事件,可以使用能效资源接口向系统申请使用公共事件资源。
对于需要升级为特权应用的,开发者需要合理评估自己的业务诉求,向应用中心提出申请。
### 接口说明
**表1** 申请能效资源主要接口
| 接口名 | 描述 |
| ---------------------------------------- | ---------------------------------------- |
| applyEfficiencyResources(request: [EfficiencyResourcesRequest](../reference/apis/js-apis-backgroundTaskManager.md#efficiencyresourcesrequest9)): boolean | 申请能效资源。 |
| resetAllEfficiencyResources():void | 释放申请的能效资源。 |
### 开发步骤
1、当特权应用需要在后台使用特殊资源时。向系统申请目标资源。
2、当资源使用完毕,需要及时释放。支持释放部分资源或全部资源。
```js
import backgroundTaskManager from '@ohos.backgroundTaskManager';
// 申请能效资源
let request = {
resourceTypes: backgroundTaskManager.ResourceType.COMMON_EVENT |
backgroundTaskManager.ResourceType.TIMER,
isApply: true,
timeOut: 0,
reason: "apply",
isPersist: true,
isProcess: true,
};
let res = backgroundTaskManager.applyEfficiencyResources(request);
console.info("the result of request is: " + res);
// 释放部分资源
request = {
resourceTypes: backgroundTaskManager.ResourceType.COMMON_EVENT,
isApply: false,
timeOut: 0,
reason: "reset",
};
res = backgroundTaskManager.applyEfficiencyResources(request);
console.info("the result of request is: " + res);
// 释放全部资源
backgroundTaskManager.resetAllEfficiencyResources();
```
## 短时任务
### 场景说明
当应用退到后台默认有6到12秒的运行时长,超过该时间后,系统会将应用置为挂起状态。对于绝大多数应用,6到12秒的时间,足够执行一些重要的任务,但如果应用需要更多的时间,可以通过短时任务接口,扩展应用的执行时间。
建议不要等到应用退后台后,才调用requestSuspendDelay方法申请延迟挂起,而是应该在执行任何的耗时操作前,都应该调用该接口,向系统申明扩展应用的执行时间。
当应用在前台时,使用requestSuspendDelay方法,不会影响应用的短时任务配额。
由于每个应用每天的短时任务配额时间有限,当执行完耗时任务后,应当及时取消延迟挂起的申请。
一些典型的耗时任务有,需要保存一些状态数据到本地数据库,需要打开和处理一个大型文件,需要同步一些数据到应用的云端服务器等。
### 接口说明
**表1** 短时任务主要接口
| 接口名 | 描述 |
| ---------------------------------------- | ---------------------------------------- |
| requestSuspendDelay(reason:&nbsp;string,&nbsp;callback:&nbsp;Callback&lt;void&gt;):&nbsp;[DelaySuspendInfo](../reference/apis/js-apis-backgroundTaskManager.md#delaysuspendinfo) | 后台应用申请延迟挂起。<br/>延迟挂起时间一般情况下默认值为180000,低电量时默认值为60000。 |
| getRemainingDelayTime(requestId:&nbsp;number):&nbsp;Promise&lt;number&gt; | 获取应用程序进入挂起状态前的剩余时间。<br/>使用Promise形式返回。 |
| cancelSuspendDelay(requestId:&nbsp;number):&nbsp;void | 取消延迟挂起。 |
### 开发步骤
1、当应用需要开始执行一个耗时的任务时。调用短时任务申请接口,并且在任务执行完后,调用短时任务取消接口。
```js
import backgroundTaskManager from '@ohos.backgroundTaskManager';
let delayInfo;
let id;
// 申请延迟挂起
function requestSuspendDelay() {
let myReason = 'test requestSuspendDelay';
delayInfo = backgroundTaskManager.requestSuspendDelay(myReason, () => {
console.info("Request suspension delay will time out.");
// 此回调函数执行,表示应用的延迟挂起申请即将超时,应用需要执行一些清理和标注工作。
});
id = delayInfo.requestId;
console.info("requestId is: " + id);
}
// 获取进入挂起前的剩余时间
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;
}
// 取消延迟挂起
function cancelSuspendDelay() {
backgroundTaskManager.cancelSuspendDelay(id);
}
function performingLongRunningTask() {
// 在执行具体的耗时任务前,调用短时任务申请接口。向系统申请延迟挂起,延长应用的后台执行时间。
requestSuspendDelay();
// 通过剩余时间查询接口,获取可用时间配额。
let delayTime = getRemainingDelayTime();
if (delayTime < 0) { // 如果时间配置少于一定的大小,考虑取消此次耗时操作。
// 处理短时任务配额时间不够的场景
cancelSuspendDelay();
return;
}
// 此处执行具体的耗时任务。
// 耗时任务执行完,调用短时任务取消接口,避免配额浪费。
cancelSuspendDelay();
}
```
......@@ -2,7 +2,7 @@
## 场景介绍
应用要执行对实时性要求不高的任务的时候,比如设备空闲时候做一次数据学习等场景,可以使用延迟调度任务,该机制在满足应用设定条件的时候,会根据系统当前状态,如内存、功耗、温度等统一决策调度时间。延迟任务调度约束见[延迟任务调度概述](./work-scheduler-overview.md)
应用要执行对实时性要求不高的任务或持久性任务的时候,比如设备空闲时候做一次数据学习等场景,可以使用延迟调度任务,该机制在满足应用设定条件的时候,会根据系统当前状态,如内存、功耗、温度等统一决策调度时间。延迟任务调度约束见[延迟任务调度约束](./background-task-overview.md#延迟任务调度约束)
## 接口说明
......@@ -34,7 +34,7 @@ isLastWorkTimeOut(workId: number): Promise\<boolean>;| 获取上次任务是否
**表2** WorkInfo包含参数
> **说明:** WorkInfo设置参数约束见[延迟任务调度概述](./work-scheduler-overview.md)
> **说明:** WorkInfo设置参数约束见[延迟任务调度约束](./background-task-overview.md#延迟任务调度约束)
参数名| 类型 |描述
---------------------------------------------------------|-----------------------------------------|---------------------------------------------------------
......@@ -61,138 +61,111 @@ onWorkStop(work: WorkInfo): void | 延迟调度任务结束回调
### 开发步骤
**开发对应的Extension**
import WorkSchedulerExtensionAbility from '@ohos.WorkSchedulerExtensionAbility';
export default class MyWorkSchedulerExtensionAbility extends WorkSchedulerExtensionAbility {
onWorkStart(workInfo) {
console.log('MyWorkSchedulerExtensionAbility onWorkStart' + JSON.stringify(workInfo));
}
onWorkStop(workInfo) {
console.log('MyWorkSchedulerExtensionAbility onWorkStop' + JSON.stringify(workInfo));
}
}
1、开发对应的ExtensionAbility,用于回调执行具体的延迟任务。关于ExtensionAbility的介绍,参考[ExtensionAbility机制](../ability/stage-brief.md#extensionability机制)
```ts
import WorkSchedulerExtensionAbility from '@ohos.WorkSchedulerExtensionAbility';
**注册延迟任务**
import workScheduler from '@ohos.workScheduler';
let workInfo = {
workId: 1,
batteryStatus:workScheduler.BatteryStatus.BATTERY_STATUS_LOW,
isRepeat: false,
isPersisted: true,
bundleName: "com.example.myapplication",
abilityName: "MyExtension",
parameters: {
mykey0: 1,
mykey1: "string value",
mykey2: true,
mykey3: 1.5
}
export default class MyExtension extends WorkSchedulerExtensionAbility {
onWorkStart(workInfo) {
console.log('MyWorkSchedulerExtensionAbility onWorkStart' + JSON.stringify(workInfo));
}
var res = workScheduler.startWork(workInfo);
console.info("workschedulerLog res:" + res);
**取消延迟任务**
import workScheduler from '@ohos.workScheduler';
let workInfo = {
workId: 1,
batteryStatus:workScheduler.BatteryStatus.BATTERY_STATUS_LOW,
isRepeat: false,
isPersisted: true,
bundleName: "com.example.myapplication",
abilityName: "MyExtension",
parameters: {
mykey0: 1,
mykey1: "string value",
mykey2: true,
mykey3: 1.5
}
onWorkStop(workInfo) {
console.log('MyWorkSchedulerExtensionAbility onWorkStop' + JSON.stringify(workInfo));
}
var res = workScheduler.stopWork(workInfo, false);
console.info("workschedulerLog res:" + res);
**获取指定延迟任务**
}
```
1.Callback写法
workScheduler.getWorkStatus(50, (err, res) => {
if (err) {
console.info('workschedulerLog getWorkStatus failed, because:' + err.code);
} else {
for (let item in res) {
console.info('workschedulerLog getWorkStatuscallback success,' + item + ' is:' + res[item]);
}
}
});
2、注册延迟任务
```ts
import workScheduler from '@ohos.workScheduler';
2.Promise写法
let workInfo = {
workId: 1,
batteryStatus:workScheduler.BatteryStatus.BATTERY_STATUS_LOW,
isRepeat: false,
isPersisted: true,
bundleName: "com.example.myapplication",
abilityName: "MyExtension",
parameters: {
mykey0: 1,
mykey1: "string value",
mykey2: true,
mykey3: 1.5
}
}
var res = workScheduler.startWork(workInfo);
console.info("workschedulerLog res:" + res);
```
workScheduler.getWorkStatus(50).then((res) => {
for (let item in res) {
console.info('workschedulerLog getWorkStatus success,' + item + ' is:' + res[item]);
}
}).catch((err) => {
console.info('workschedulerLog getWorkStatus failed, because:' + err.code);
})
3、取消延迟任务
**获取所有延迟任务**
```ts
import workScheduler from '@ohos.workScheduler';
1.Callback写法
let workInfo = {
workId: 1,
batteryStatus:workScheduler.BatteryStatus.BATTERY_STATUS_LOW,
isRepeat: false,
isPersisted: true,
bundleName: "com.example.myapplication",
abilityName: "MyExtension",
parameters: {
mykey0: 1,
mykey1: "string value",
mykey2: true,
mykey3: 1.5
}
}
var res = workScheduler.stopWork(workInfo, false);
console.info("workschedulerLog res:" + res);
```
workScheduler.obtainAllWorks((err, res) =>{
if (err) {
console.info('workschedulerLog obtainAllWorks failed, because:' + err.code);
} else {
console.info('workschedulerLog obtainAllWorks success, data is:' + JSON.stringify(res));
}
});
2.Promise写法
4、获取指定延迟任务
workScheduler.obtainAllWorks().then((res) => {
console.info('workschedulerLog obtainAllWorks success, data is:' + JSON.stringify(res));
}).catch((err) => {
console.info('workschedulerLog obtainAllWorks failed, because:' + err.code);
})
```ts
workScheduler.getWorkStatus(50).then((res) => {
for (let item in res) {
console.info('workschedulerLog getWorkStatus success,' + item + ' is:' + res[item]);
}
}).catch((err) => {
console.info('workschedulerLog getWorkStatus failed, because:' + err.code);
})
```
**停止并清除任务**
let res = workScheduler.stopAndClearWorks();
console.info("workschedulerLog res:" + res);
5、获取所有延迟任务
**判断上次执行是否超时**
```ts
workScheduler.obtainAllWorks().then((res) => {
console.info('workschedulerLog obtainAllWorks success, data is:' + JSON.stringify(res));
}).catch((err) => {
console.info('workschedulerLog obtainAllWorks failed, because:' + err.code);
})
```
1.Callback写法
6、停止并清除任务
workScheduler.isLastWorkTimeOut(500, (err, res) =>{
if (err) {
console.info('workschedulerLog isLastWorkTimeOut failed, because:' + err.code);
} else {
console.info('workschedulerLog isLastWorkTimeOut success, data is:' + res);
}
});
```ts
let res = workScheduler.stopAndClearWorks();
console.info("workschedulerLog res:" + res);
```
2.Promise写法
7、判断上次执行是否超时
workScheduler.isLastWorkTimeOut(500)
.then(res => {
console.info('workschedulerLog isLastWorkTimeOut success, data is:' + res);
})
.catch(err => {
console.info('workschedulerLog isLastWorkTimeOut failed, because:' + err.code);
});
})
```ts
workScheduler.isLastWorkTimeOut(500)
.then(res => {
console.info('workschedulerLog isLastWorkTimeOut success, data is:' + res);
})
.catch(err => {
console.info('workschedulerLog isLastWorkTimeOut failed, because:' + err.code);
});
```
## 相关实例
......
# 延迟任务调度概述
延迟任务调度给应用提供一个机制,允许应用根据系统安排,在系统空闲时执行实时性不高的任务。当满足设定条件的时候,任务会被放入待调度队列,当系统空闲时调度该任务。
## 使用说明
应用要执行对实时性要求不高的任务的时候,比如设备空闲时候做一次数据学习等场景,可以使用延迟调度任务,该机制在满足应用设定条件的时候,会根据系统当前状态,如内存、功耗、温度等统一决策调度时机。
## 延迟任务调度约束
延迟调度任务的使用需要遵从如下约束和规则:
- **超时**:系统会设置超时机制,延迟任务回调只允许运行一段时间,超时之后,系统会主动停止。默认的超时限制为2分钟,对于系统应用,可以通过[能效资源申请接口](background-task-overview.md#能效资源申请)获取更长的执行时间(充电状态20分钟,非充电状态10分钟)。
- **执行频率**:系统会根据应用的活跃度对延迟任务做分级管控,限制延迟任务调度的执行频率。对于通过能效资源接口申请了WORK_SCHEDULER资源的应用,在资源的有效期内,它的延迟任务执行频率不受限制。
应用分组 | 延迟任务执行频率约束
--------------------|-------------------------
活跃 | 最小间隔2小时
每日使用 | 最小间隔4小时
经常使用 | 最小间隔24小时
不经常使用 | 最小间隔48小时
受限分组 | 禁止
未使用分组 | 禁止
[能效资源豁免分组](../reference/apis/js-apis-backgroundTaskManager.md#resourcetype9) | 执行频率不受限制
- **WorkInfo设置参数约束**
(1) workId、bundleName、abilityName为必填项,bundleName必须填本应用,否则校验失败。
(2)至少要设置一个满足的条件。
(3)重复任务时间间隔至少20分钟,当设置重复任务时间间隔时,必须设置始终重复和重复次数中的一个。
(4)携带参数信息支持number、string、bool三种类型。
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册