1# 后台任务开发指导 2 3## 场景介绍 4 5应用或业务模块处于后台(无可见界面)时,如果有需要继续执行或者后续执行的业务,可基于业务类型,申请短时任务延迟挂起(Suspend)或者长时任务避免进入挂起状态。 6 7## 短时任务 8 9### 接口说明 10 11**表1** 短时任务主要接口 12 13| 接口名 | 描述 | 14| -------- | -------- | 15| requestSuspendDelay(reason: string, callback: Callback<void>): [DelaySuspendInfo](../reference/apis/js-apis-backgroundTaskManager.md#delaysuspendinfo) | 后台应用申请延迟挂起。<br/>延迟挂起时间一般情况下默认值为180000毫秒,低电量时默认值为60000毫秒。 | 16| getRemainingDelayTime(requestId: number): Promise<number> | 获取应用程序进入挂起状态前的剩余时间。<br/>使用Promise形式返回。 | 17| cancelSuspendDelay(requestId: number): 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<void> | 服务启动后,向系统申请长时任务,使服务一直保持后台运行。 | 97| stopBackgroundRunning(context: Context): Promise<void> | 停止后台长时任务的运行。 | 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)