1# PageAbility开发指导 2 3## 概述 4### 功能简介 5PageAbility是具备ArkUI实现的Ability,是开发者具体可见并可以交互的Ability实例。开发者通过IDE创建Ability时,IDE会自动创建相关模板代码。PageAbility相关能力通过单独的featureAbility实现,生命周期相关回调则通过app.js/app.ets中各个回调函数实现。 6 7### PageAbility的生命周期 8 9**PageAbility生命周期介绍**(Ability Life Cycle): 10 11PageAbility生命周期是PageAbility被调度到INACTIVE、ACTIVE、BACKGROUND等各个状态的统称。 12 13PageAbility生命周期流转如下图所示: 14 15 16 17 18**Ability生命周期状态说明:** 19 20 - **UNINITIALIZED**:未初始状态,为临时状态,PageAbility被创建后会由UNINITIALIZED状态进入INITIAL状态。 21 22 - **INITIAL**:初始化状态,也表示停止状态,表示当前PageAbility未运行,PageAbility被启动后由INITIAL态进入INACTIVE状态。 23 24 - **INACTIVE**:失去焦点状态,表示当前窗口已显示但是无焦点状态。 25 26 - **ACTIVE**:前台激活状态,表示当前窗口已显示,并获取焦点。 27 28 - **BACKGROUND**:后台状态,表示当前PageAbility退到后台,PageAbility在被销毁后由BACKGROUND状态进入INITIAL状态,或者重新被激活后由BACKGROUND状态进入ACTIVE状态。 29 30**PageAbility生命周期回调与生命周期状态的关系如下图所示:** 31 32 33 34PageAbility提供生命周期回调,开发者可以在`app.js/app.ets`中重写生命周期相关回调函数 。目前`app.js`环境中仅支持onCreate和onDestroy回调,`app.ets`环境支持全量生命周期回调。 35 36### 启动模式 37ability支持单实例和多实例两种启动模式。 38在config.json中通过launchType配置项,可以配置具体的启动模式,其中: 39 40| 启动模式 | 描述 |说明 | 41| ----------- | ------- |---------------- | 42| standard | 多实例 | 每次startAbility都会启动一个新的实例 | 43| singleton | 单实例 | 系统中只存在唯一一个实例,startAbility时,如果已存在,则复用系统中的唯一一个实例 | 44 45缺省情况下是singleton模式。 46 47 48## 开发指导 49### featureAbility接口说明 50 51**表1** featureAbility接口介绍 52 53| 接口名 | 描述 | 54| --------------------------------------------------- | --------------- | 55| void startAbility(parameter: StartAbilityParameter) | 启动Ability | 56| Context getContext(): | 获取应用Context | 57| void terminateSelf() | 结束Ability | 58| bool hasWindowFocus() | 是否获取焦点 | 59 60 61### 启动本地PageAbility 62 63**导入模块** 64 65```js 66 import featureAbility from '@ohos.ability.featureAbility' 67``` 68 69**示例** 70 71```javascript 72 import featureAbility from '@ohos.ability.featureAbility' 73 featureAbility.startAbility({ 74 want: 75 { 76 action: "", 77 entities: [""], 78 type: "", 79 options: { 80 // Grant the permission to perform read operations on the URI. 81 authReadUriPermission: true, 82 // Grant the permission to perform write operations on the URI. 83 authWriteUriPermission: true, 84 // support forwarding the Want result to the ability. 85 abilityForwardResult: true, 86 // Enable abiligy continuation. 87 abilityContinuation: true, 88 // Specify that a component does not belong to ohos. 89 notOhosComponent: true, 90 // Specify that an ability is started. 91 abilityFormEnabled: true, 92 // Grant the permission for possible persisting on the URI. 93 authPersistableUriPermission: true, 94 // Grant the permission for possible persisting on the prefix URI. 95 authPrefixUriPermission: true, 96 // Support distributed scheduling system startup on multiple devices. 97 abilitySliceMultiDevice: true, 98 // A service ability is started regardless of whether the host application has been started. 99 startForegroundAbility: true, 100 // Install the specified ability if it is not installed. 101 installOnDemand: true, 102 // Return the result to the ability slice. 103 abilitySliceForwardResult: true, 104 // Install the specified ability with background mode if it is not installed. 105 installWithBackgroundMode: true 106 }, 107 deviceId: "", 108 bundleName: "com.example.startability", 109 abilityName: "com.example.startability.MainAbility", 110 uri: "" 111 }, 112 }, 113 ); 114``` 115 116`want`参数也可以使用parameters参数,使用key-value的方式输入。 117 118**示例** 119 120```javascript 121 import featureAbility from '@ohos.ability.featureAbility' 122 featureAbility.startAbility({ 123 want: 124 { 125 bundleName: "com.example.startability", 126 uri: "", 127 parameters: { 128 abilityName: "com.example.startability.MainAbility" 129 } 130 }, 131 }, 132 ); 133``` 134### 启动远程PageAbility(当前仅对系统应用开放) 135>说明:由于DeviceManager的getTrustedDeviceListSync接口仅对系统应用开放,当前启动远程PageAbility仅支持系统应用 136 137**导入模块** 138 139``` 140 import featureAbility from '@ohos.ability.featureAbility' 141 import deviceManager from '@ohos.distributedHardware.deviceManager'; 142``` 143 144**示例** 145```ts 146 function onStartRemoteAbility() { 147 console.info('onStartRemoteAbility begin'); 148 let params; 149 let wantValue = { 150 bundleName: 'ohos.samples.etsDemo', 151 abilityName: 'ohos.samples.etsDemo.RemoteAbility', 152 deviceId: getRemoteDeviceId(), 153 parameters: params 154 }; 155 console.info('onStartRemoteAbility want=' + JSON.stringify(wantValue)); 156 featureAbility.startAbility({ 157 want: wantValue 158 }).then((data) => { 159 console.info('onStartRemoteAbility finished, ' + JSON.stringify(data)); 160 }); 161 console.info('onStartRemoteAbility end'); 162 } 163``` 164 165从DeviceManager获取`deviceId`,具体示例代码如下: 166 167```ts 168 import deviceManager from '@ohos.distributedHardware.deviceManager'; 169 let dmClass; 170 function getRemoteDeviceId() { 171 if (typeof dmClass === 'object' && dmClass != null) { 172 let list = dmClass.getTrustedDeviceListSync(); 173 if (typeof (list) == 'undefined' || typeof (list.length) == 'undefined') { 174 console.log("MainAbility onButtonClick getRemoteDeviceId err: list is null"); 175 return; 176 } 177 console.log("MainAbility onButtonClick getRemoteDeviceId success:" + list[0].deviceId); 178 return list[0].deviceId; 179 } else { 180 console.log("MainAbility onButtonClick getRemoteDeviceId err: dmClass is null"); 181 } 182 } 183``` 184 185在跨设备场景下,需要向用户申请数据同步的权限。具体示例代码如下: 186 187```ts 188 import abilityAccessCtrl from "@ohos.abilityAccessCtrl"; 189 import bundle from '@ohos.bundle'; 190 async function RequestPermission() { 191 console.info('RequestPermission begin'); 192 let array: Array<string> = ["ohos.permission.DISTRIBUTED_DATASYNC"]; 193 let bundleFlag = 0; 194 let tokenID = undefined; 195 let userID = 100; 196 let appInfo = await bundle.getApplicationInfo('ohos.samples.etsDemo', bundleFlag, userID); 197 tokenID = appInfo.accessTokenId; 198 let atManager = abilityAccessCtrl.createAtManager(); 199 let requestPermissions: Array<string> = []; 200 for (let i = 0;i < array.length; i++) { 201 let result = await atManager.verifyAccessToken(tokenID, array[i]); 202 console.info("verifyAccessToken result:" + JSON.stringify(result)); 203 if (result == abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) { 204 } else { 205 requestPermissions.push(array[i]); 206 } 207 } 208 console.info("requestPermissions:" + JSON.stringify(requestPermissions)); 209 if (requestPermissions.length == 0 || requestPermissions == []) { 210 return; 211 } 212 let context = featureAbility.getContext(); 213 context.requestPermissionsFromUser(requestPermissions, 1, (data)=>{ 214 console.info("data:" + JSON.stringify(data)); 215 console.info("data requestCode:" + data.requestCode); 216 console.info("data permissions:" + data.permissions); 217 console.info("data authResults:" + data.authResults); 218 }); 219 console.info('RequestPermission end'); 220 } 221``` 222 223### 生命周期接口说明 224 225**表2** 生命周期回调函数介绍 226 227| 接口名 | 描述 | 228| ------------ | ------------------------------------------------------------ | 229| onShow() | Ability由后台不可见状态切换到前台可见状态调用onShow方法,此时用户在屏幕可以看到该Ability | 230| onHide() | Ability由前台切换到后台不可见状态时调用onHide方法,此时用户在屏幕看不到该Ability。 | 231| onDestroy() | 应用退出,销毁Ability对象前调用onDestroy方法,开发者可以在该方法里做一些回收资源、清空缓存等应用退出前的准备工作。 | 232| onCreate() | Ability第一次启动创建Ability时调用onCreate方法,开发者可以在该方法里做一些应用初始化工作。 | 233| onInactive() | Ability失去焦点时调用onInactive方法,Ability在进入后台状态时会先失去焦点,再进入后台。 | 234| onActive() | Ability切换到前台,并且已经获取焦点时调用onActive方法。 | 235 236**示例** 237 238开发者需要重写`app.js/app.ets`中相关生命周期回调函数,IDE模板默认生成`onCreate()`和`onDestroy()`方法,其他方法需要开发者自行实现。 239 240```javascript 241export default { 242 onCreate() { 243 console.info('Application onCreate') 244 }, 245 onDestroy() { 246 console.info('Application onDestroy') 247 }, 248 onShow(){ 249 console.info('Application onShow') 250 }, 251 onHide(){ 252 console.info('Application onHide') 253 }, 254 onInactive(){ 255 console.info('Application onInactive') 256 }, 257 onActive(){ 258 console.info('Application onActive') 259 }, 260} 261``` 262## 相关实例 263针对PageAbility开发,有以下相关实例可供参考: 264- [`DMS`:分布式Demo(eTS)(API8)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/samples_monthly_0730/ability/DMS)