• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 后台任务开发指导
2
3## 场景介绍
4
5应用或业务模块处于后台(无可见界面)时,如果有需要继续执行或者后续执行的业务,可基于业务类型,申请短时任务延迟挂起(Suspend)或者长时任务避免进入挂起状态。
6
7## 短时任务
8
9### 接口说明
10
11**表1** 短时任务主要接口
12
13| 接口名 | 描述 |
14| -------- | -------- |
15| requestSuspendDelay(reason:&nbsp;string,&nbsp;callback:&nbsp;Callback&lt;void&gt;):&nbsp;[DelaySuspendInfo](../reference/apis/js-apis-backgroundTaskManager.md#delaysuspendinfo) | 后台应用申请延迟挂起。<br/>延迟挂起时间一般情况下默认值为180000毫秒,低电量时默认值为60000毫秒。 |
16| getRemainingDelayTime(requestId:&nbsp;number):&nbsp;Promise&lt;number&gt; | 获取应用程序进入挂起状态前的剩余时间。<br/>使用Promise形式返回。 |
17| cancelSuspendDelay(requestId:&nbsp;number):&nbsp;void | 取消延迟挂起。 |
18
19
20### 开发步骤
21
22
231. 申请延迟挂起
24
25    ```js
26    import backgroundTaskManager from '@ohos.backgroundTaskManager';
27
28    let myReason = 'test requestSuspendDelay';
29    let delayInfo = backgroundTaskManager.requestSuspendDelay(myReason, () => {
30        console.info("Request suspension delay will time out.");
31    });
32
33    var id = delayInfo.requestId;
34    console.info("requestId is: " + id);
35    ```
36
37
382. 获取进入挂起前的剩余时间
39
40    ```js
41    backgroundTaskManager.getRemainingDelayTime(id).then( res => {
42        console.log('promise => Operation getRemainingDelayTime succeeded. Data: ' + JSON.stringify(res));
43    }).catch( err => {
44        console.log('promise => Operation getRemainingDelayTime failed. Cause: ' + err.code);
45    });
46    ```
47
48
493. 取消延迟挂起
50
51    ```js
52    backgroundTaskManager.cancelSuspendDelay(id);
53    ```
54
55
56### 开发实例
57
58```js
59import backgroundTaskManager from '@ohos.backgroundTaskManager';
60let myReason = 'test requestSuspendDelay';
61
62// 申请延迟挂起
63let delayInfo = backgroundTaskManager.requestSuspendDelay(myReason, () => {
64    console.info("Request suspension delay will time out.");
65});
66
67// 打印延迟挂起信息
68var id = delayInfo.requestId;
69var time = delayInfo.actualDelayTime;
70console.info("The requestId is: " + id);
71console.info("The actualDelayTime is: " + time);
72
73// 获取应用程序进入挂起状态前的剩余时间
74backgroundTaskManager.getRemainingDelayTime(id).then( res => {
75    console.log('promise => Operation getRemainingDelayTime succeeded. Data: ' + JSON.stringify(res));
76}).catch( err => {
77    console.log('promise => Operation getRemainingDelayTime failed. Cause: ' + err.code);
78});
79
80// 取消延迟挂起
81backgroundTaskManager.cancelSuspendDelay(id);
82```
83
84## 长时任务
85
86### 权限
87
88ohos.permission.KEEP_BACKGROUND_RUNNING
89
90### 接口说明
91
92**表2** 长时任务主要接口
93
94| 接口名 | 描述 |
95| -------- | -------- |
96| startBackgroundRunning(context: Context, bgMode: BackgroundMode, wantAgent: WantAgent): Promise&lt;void&gt; | 服务启动后,向系统申请长时任务,使服务一直保持后台运行。 |
97| stopBackgroundRunning(context: Context): Promise&lt;void&gt; | 停止后台长时任务的运行。 |
98
99
100其中,wantAgent的信息详见([WantAgent](../reference/apis/js-apis-wantAgent.md))
101
102**表3** 后台模式类型
103
104| 参数名 | id值 | 描述 | 配置项 |
105| -------- | -------- | -------- | -------- |
106| DATA_TRANSFER           | 1 | 数据传输 | dataTransfer |
107| AUDIO_PLAYBACK          | 2 | 音频播放 | audioPlayback |
108| AUDIO_RECORDING         | 3 | 录音 | audioRecording |
109| LOCATION                | 4 | 定位导航 | location |
110| BLUETOOTH_INTERACTION   | 5 | 蓝牙相关 | bluetoothInteraction |
111| MULTI_DEVICE_CONNECTION | 6 | 多设备互联 | multiDeviceConnection |
112| WIFI_INTERACTION        | 7 | WLAN相关(系统保留) | wifiInteraction |
113| VOIP                    | 8 | 音视频通话(系统保留) | voip |
114| TASK_KEEPING            | 9 | 计算任务(仅供特定设备使用) | taskKeeping |
115
116
117### 开发步骤
118
1191. 新建Api Version 8的工程后,在工程目录中右键选择“new” -> “Ability” -> “Service Ability” 快速创建Service Ability组件。并在config.json文件中配置长时任务权限、后台模式类型,其中Ability类型为“service”。
120
121    ```
122    "module": {
123      "package": "com.example.myapplication",
124      "abilities": [
125        {
126          "backgroundModes": [
127            "dataTransfer",
128            "location"
129          ], // 后台模式类型
130          "type": "service"  // ability类型为service
131        }
132      ],
133      "reqPermissions": [
134        {
135          "name": "ohos.permission.KEEP_BACKGROUND_RUNNING"  // 长时任务权限
136        }
137      ]
138    }
139    ```
140
1412. 申请长时任务
142
143    ```js
144    import backgroundTaskManager from '@ohos.backgroundTaskManager';
145    import featureAbility from '@ohos.ability.featureAbility';
146    import wantAgent from '@ohos.wantAgent';
147
148    let wantAgentInfo = {
149        wants: [
150            {
151                bundleName: "com.example.myapplication",
152                abilityName: "com.example.myapplication.MainAbility"
153            }
154        ],
155        operationType: wantAgent.OperationType.START_ABILITY,
156        requestCode: 0,
157        wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG]
158    };
159
160    // 通过wantAgent模块的getWantAgent方法获取WantAgent对象
161    wantAgent.getWantAgent(wantAgentInfo).then((wantAgentObj) => {
162        backgroundTaskManager.startBackgroundRunning(featureAbility.getContext(),
163            backgroundTaskManager.BackgroundMode.DATA_TRANSFER, wantAgentObj).then(() => {
164            console.info("Operation startBackgroundRunning succeeded");
165        }).catch((err) => {
166            console.error("Operation startBackgroundRunning failed Cause: " + err);
167        });
168    });
169    ```
170
1713. 停止长时任务
172
173    ```js
174    import backgroundTaskManager from '@ohos.backgroundTaskManager';
175    import featureAbility from '@ohos.ability.featureAbility';
176
177    backgroundTaskManager.stopBackgroundRunning(featureAbility.getContext()).then(() => {
178        console.info("Operation stopBackgroundRunning succeeded");
179    }).catch((err) => {
180        console.error("Operation stopBackgroundRunning failed Cause: " + err);
181    });
182
183    ```
184
185### 开发实例
186基于FA的Service Ability使用,参考[ServiceAbility开发指导](../ability/fa-serviceability.md)。
187
188当不需要与后台执行的长时任务交互时,可以采用startAbility()方法启动Service Ability。并在Service Ability的onStart回调方法中,调用长时任务的申请接口,声明此服务需要在后台长时运行。当任务执行完,再调用长时任务取消接口,及时释放资源。
189
190当需要与后台执行的长时任务交互时(如播放音乐等)。可以采用connectAbility()方法启动并连接Service Ability。在获取到服务的代理对象后,与服务进行通信,控制长时任务的申请和取消。
191
192```js
193import backgroundTaskManager from '@ohos.backgroundTaskManager';
194import featureAbility from '@ohos.ability.featureAbility';
195import wantAgent from '@ohos.wantAgent';
196import rpc from "@ohos.rpc";
197
198function startContinuousTask() {
199    let wantAgentInfo = {
200        // 点击通知后,将要执行的动作列表
201        wants: [
202            {
203                bundleName: "com.example.myapplication",
204                abilityName: "com.example.myapplication.MainAbility"
205            }
206        ],
207        // 点击通知后,动作类型
208        operationType: wantAgent.OperationType.START_ABILITY,
209        // 使用者自定义的一个私有值
210        requestCode: 0,
211        // 点击通知后,动作执行属性
212        wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG]
213    };
214
215    // 通过wantAgent模块的getWantAgent方法获取WantAgent对象
216    wantAgent.getWantAgent(wantAgentInfo).then((wantAgentObj) => {
217        backgroundTaskManager.startBackgroundRunning(featureAbility.getContext(),
218            backgroundTaskManager.BackgroundMode.DATA_TRANSFER, wantAgentObj).then(() => {
219            console.info("Operation startBackgroundRunning succeeded");
220        }).catch((err) => {
221            console.error("Operation startBackgroundRunning failed Cause: " + err);
222        });
223    });
224}
225
226function stopContinuousTask() {
227    backgroundTaskManager.stopBackgroundRunning(featureAbility.getContext()).then(() => {
228        console.info("Operation stopBackgroundRunning succeeded");
229    }).catch((err) => {
230        console.error("Operation stopBackgroundRunning failed Cause: " + err);
231    });
232}
233
234async function processAsyncJobs() {
235    // 此处执行具体的长时任务。
236
237    // 长时任务执行完,调用取消接口,释放资源。
238    stopContinuousTask();
239}
240
241let mMyStub;
242
243class MyStub extends rpc.RemoteObject {
244    constructor(des) {
245        if (typeof des === 'string') {
246            super(des);
247        } else {
248            return null;
249        }
250    }
251    onRemoteRequest(code, data, reply, option) {
252        console.log('ServiceAbility onRemoteRequest called');
253        // code 的具体含义用户自定义
254        if (code === 1) {
255            // 接收到申请长时任务的请求码
256            startContinuousTask();
257            // 此处执行具体长时任务
258        } else if (code === 2) {
259            // 接收到取消长时任务的请求码
260            stopContinuousTask();
261        } else {
262            console.log('ServiceAbility unknown request code');
263        }
264        return true;
265    }
266}
267
268export default {
269    onStart(want) {
270        console.info('ServiceAbility onStart');
271        mMyStub = new MyStub("ServiceAbility-test");
272        // 在执行后台长时任前,调用申请接口。
273        startContinuousTask();
274        processAsyncJobs();
275    },
276    onStop() {
277        console.info('ServiceAbility onStop');
278    },
279    onConnect(want) {
280        console.info('ServiceAbility onConnect');
281        return mMyStub;
282    },
283    onReconnect(want) {
284        console.info('ServiceAbility onReconnect');
285    },
286    onDisconnect() {
287        console.info('ServiceAbility onDisconnect');
288    },
289    onCommand(want, restart, startId) {
290        console.info('ServiceAbility onCommand');
291    }
292};
293```
294
295## 相关实例
296
297基于后台任务管理,有以下相关实例可供参考:
298
299- [`BackgroundTaskManager`:后台任务管理(eTS)(API8)](https://gitee.com/openharmony/applications_app_samples/tree/samples_monthly_0730/ResourcesSchedule/BackgroundTaskManager)