1# PageAbility开发指导 2 3## 概述 4 5### 功能简介 6 7PageAbility是具备ArkUI实现的Ability,是开发者具体可见并可以与之交互的Ability实例。开发者通过DevEco Studio创建Ability时,DevEco Studio会自动创建相关模板代码。 8 9PageAbility相关能力通过单独的featureAbility实现,生命周期相关回调则通过`app.js/app.ets`中各个回调函数实现。 10 11### PageAbility的生命周期 12 13**PageAbility生命周期介绍**(Ability Lifecycle): 14 15PageAbility生命周期是PageAbility被调度到INACTIVE、ACTIVE、BACKGROUND等各个状态的统称。 16 17PageAbility生命周期流转如下图所示: 18 19![PageAbility-Lifecycle](figures/page-ability-lifecycle.png) 20 21 22**Ability生命周期状态说明:** 23 24 - **UNINITIALIZED**:未初始状态,为临时状态,PageAbility被创建后会由UNINITIALIZED状态进入INITIAL状态。 25 26 - **INITIAL**:初始化状态,也表示停止状态,表示当前PageAbility未运行,PageAbility被启动后由INITIAL态进入INACTIVE状态。 27 28 - **INACTIVE**:失去焦点状态,表示当前窗口已显示但是无焦点状态。 29 30 - **ACTIVE**:前台激活状态,表示当前窗口已显示,并获取焦点。 31 32 - **BACKGROUND**:后台状态,表示当前PageAbility退到后台,PageAbility在被销毁后由BACKGROUND状态进入INITIAL状态,或者重新被激活后由BACKGROUND状态进入ACTIVE状态。 33 34**PageAbility生命周期回调与生命周期状态的关系如下图所示:** 35 36![fa-pageAbility-lifecycle](figures/fa-pageAbility-lifecycle.png) 37 38PageAbility提供生命周期回调,开发者可以在`app.js/app.ets`中重写生命周期相关回调函数 。目前`app.js`环境中仅支持onCreate和onDestroy回调,`app.ets`环境支持全量生命周期回调。 39 40### 启动模式 41 42ability支持单实例和多实例两种启动模式。 43 44在`config.json`中通过launchType配置项,可以配置具体的启动模式,其中: 45 46**表1** 启动模式介绍 47 48| 启动模式 | 描述 |说明 | 49| ----------- | ------- |---------------- | 50| standard | 多实例模式 | 每次startAbility都会启动一个新的实例。 | 51| singleton | 单实例模式 | 系统中只存在唯一一个实例,startAbility时,如果已存在,则复用系统中的唯一一个实例。 | 52 53缺省情况下是singleton模式。 54 55 56## 开发指导 57 58### featureAbility接口说明 59 60**表2** featureAbility接口介绍 61 62| 接口名 | 描述 | 63| --------------------------------------------------- | --------------- | 64| void startAbility(parameter: StartAbilityParameter) | 启动Ability。 | 65| Context getContext(): | 获取应用Context。 | 66| void terminateSelf() | 结束Ability。 | 67| bool hasWindowFocus() | 是否获取焦点。 | 68 69 70### 启动本地PageAbility 71 72**导入模块** 73 74```js 75 import featureAbility from '@ohos.ability.featureAbility' 76``` 77 78**示例** 79 80```javascript 81 import featureAbility from '@ohos.ability.featureAbility' 82 featureAbility.startAbility({ 83 want: { 84 action: "", 85 entities: [""], 86 type: "", 87 deviceId: "", 88 bundleName: "com.example.myapplication", 89 /* FA模型中abilityName由package + Ability name组成 */ 90 abilityName: "com.example.entry.secondAbility", 91 uri: "" 92 } 93 }); 94``` 95 96### 启动远程PageAbility(当前仅对系统应用开放) 97 98>说明:由于DeviceManager的getTrustedDeviceListSync接口仅对系统应用开放,当前启动远程PageAbility仅支持系统应用。 99 100**导入模块** 101 102``` 103 import featureAbility from '@ohos.ability.featureAbility' 104 import deviceManager from '@ohos.distributedHardware.deviceManager'; 105``` 106 107**示例** 108```ts 109 function onStartRemoteAbility() { 110 console.info('onStartRemoteAbility begin'); 111 let params; 112 let wantValue = { 113 bundleName: 'ohos.samples.etsDemo', 114 abilityName: 'ohos.samples.etsDemo.RemoteAbility', 115 deviceId: getRemoteDeviceId(), 116 parameters: params 117 }; 118 console.info('onStartRemoteAbility want=' + JSON.stringify(wantValue)); 119 featureAbility.startAbility({ 120 want: wantValue 121 }).then((data) => { 122 console.info('onStartRemoteAbility finished, ' + JSON.stringify(data)); 123 }); 124 console.info('onStartRemoteAbility end'); 125 } 126``` 127 128从DeviceManager获取`deviceId`,具体示例代码如下: 129 130```ts 131 import deviceManager from '@ohos.distributedHardware.deviceManager'; 132 let dmClass; 133 function getRemoteDeviceId() { 134 if (typeof dmClass === 'object' && dmClass != null) { 135 let list = dmClass.getTrustedDeviceListSync(); 136 if (typeof (list) == 'undefined' || typeof (list.length) == 'undefined') { 137 console.log("MainAbility onButtonClick getRemoteDeviceId err: list is null"); 138 return; 139 } 140 console.log("MainAbility onButtonClick getRemoteDeviceId success:" + list[0].deviceId); 141 return list[0].deviceId; 142 } else { 143 console.log("MainAbility onButtonClick getRemoteDeviceId err: dmClass is null"); 144 } 145 } 146``` 147 148在跨设备场景下,需要向用户申请数据同步的权限。具体示例代码如下: 149 150```ts 151 import abilityAccessCtrl from "@ohos.abilityAccessCtrl"; 152 import bundle from '@ohos.bundle'; 153 async function RequestPermission() { 154 console.info('RequestPermission begin'); 155 let array: Array<string> = ["ohos.permission.DISTRIBUTED_DATASYNC"]; 156 let bundleFlag = 0; 157 let tokenID = undefined; 158 let userID = 100; 159 let appInfo = await bundle.getApplicationInfo('ohos.samples.etsDemo', bundleFlag, userID); 160 tokenID = appInfo.accessTokenId; 161 let atManager = abilityAccessCtrl.createAtManager(); 162 let requestPermissions: Array<string> = []; 163 for (let i = 0;i < array.length; i++) { 164 let result = await atManager.verifyAccessToken(tokenID, array[i]); 165 console.info("verifyAccessToken result:" + JSON.stringify(result)); 166 if (result != abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) { 167 requestPermissions.push(array[i]); 168 } 169 } 170 console.info("requestPermissions:" + JSON.stringify(requestPermissions)); 171 if (requestPermissions.length == 0 || requestPermissions == []) { 172 return; 173 } 174 let context = featureAbility.getContext(); 175 context.requestPermissionsFromUser(requestPermissions, 1, (data)=>{ 176 console.info("data:" + JSON.stringify(data)); 177 console.info("data requestCode:" + data.requestCode); 178 console.info("data permissions:" + data.permissions); 179 console.info("data authResults:" + data.authResults); 180 }); 181 console.info('RequestPermission end'); 182 } 183``` 184 185### 生命周期接口说明 186 187**表3** 生命周期回调函数介绍 188 189| 接口名 | 描述 | 190| ------------ | ------------------------------------------------------------ | 191| onShow() | Ability由后台不可见状态切换到前台可见状态调用onShow方法,此时用户在屏幕可以看到该Ability。 | 192| onHide() | Ability由前台切换到后台不可见状态时调用onHide方法,此时用户在屏幕看不到该Ability。 | 193| onDestroy() | 应用退出,销毁Ability对象前调用onDestroy方法,开发者可以在该方法里做一些回收资源、清空缓存等应用退出前的准备工作。 | 194| onCreate() | Ability第一次启动创建Ability时调用onCreate方法,开发者可以在该方法里做一些应用初始化工作。 | 195| onInactive() | Ability失去焦点时调用onInactive方法,Ability在进入后台状态时会先失去焦点,再进入后台。 | 196| onActive() | Ability切换到前台,并且已经获取焦点时调用onActive方法。 | 197 198**示例** 199 200开发者需要重写`app.js/app.ets`中相关生命周期回调函数,DevEco Studio模板默认生成`onCreate()`和`onDestroy()`方法,其他方法需要开发者自行实现。 201 202```javascript 203export default { 204 onCreate() { 205 console.info('Application onCreate') 206 }, 207 onDestroy() { 208 console.info('Application onDestroy') 209 }, 210 onShow(){ 211 console.info('Application onShow') 212 }, 213 onHide(){ 214 console.info('Application onHide') 215 }, 216 onInactive(){ 217 console.info('Application onInactive') 218 }, 219 onActive(){ 220 console.info('Application onActive') 221 }, 222} 223```