fa-pageability.md 10.0 KB
Newer Older
1
# PageAbility开发指导
Z
zhaoyuan 已提交
2

G
guyuanzhang 已提交
3 4
## 概述
### 功能简介
R
RayShih 已提交
5
PageAbility是具备ArkUI实现的Ability,是开发者具体可见并可以交互的Ability实例。开发者通过IDE创建Ability时,IDE会自动创建相关模板代码。PageAbility相关能力通过单独的featureAbility实现,生命周期相关回调则通过app.js/app.ets中各个回调函数实现。
Z
zhaoyuan 已提交
6

G
guyuanzhang 已提交
7
### PageAbility的生命周期
Z
zhaoyuan 已提交
8

R
RayShih 已提交
9
**PageAbility生命周期介绍**(Ability Life Cycle):
Z
zhaoyuan 已提交
10

R
RayShih 已提交
11 12 13
PageAbility生命周期是PageAbility被调度到INACTIVE、ACTIVE、BACKGROUND等各个状态的统称。

PageAbility生命周期流转如下图所示:
Z
zhaoyuan 已提交
14 15 16 17 18 19

![PageAbility-Lifecycle](figures/page-ability-lifecycle.png)


**Ability生命周期状态说明:**

R
RayShih 已提交
20
  - **UNINITIALIZED**:未初始状态,为临时状态,PageAbility被创建后会由UNINITIALIZED状态进入INITIAL状态。
Z
zhaoyuan 已提交
21

R
RayShih 已提交
22
  - **INITIAL**:初始化状态,也表示停止状态,表示当前PageAbility未运行,PageAbility被启动后由INITIAL态进入INACTIVE状态。
Z
zhaoyuan 已提交
23

G
guyuanzhang 已提交
24
  - **INACTIVE**:失去焦点状态,表示当前窗口已显示但是无焦点状态。
Z
zhaoyuan 已提交
25

G
guyuanzhang 已提交
26
  - **ACTIVE**:前台激活状态,表示当前窗口已显示,并获取焦点。
Z
zhaoyuan 已提交
27

R
RayShih 已提交
28
  - **BACKGROUND**:后台状态,表示当前PageAbility退到后台,PageAbility在被销毁后由BACKGROUND状态进入INITIAL状态,或者重新被激活后由BACKGROUND状态进入ACTIVE状态。
Z
zhaoyuan 已提交
29

R
RayShih 已提交
30
**PageAbility生命周期回调与生命周期状态的关系如下图所示:**
Z
zhaoyuan 已提交
31

Z
zengyawen 已提交
32
![fa-pageAbility-lifecycle](figures/fa-pageAbility-lifecycle.png)
Z
zhaoyuan 已提交
33

G
guyuanzhang 已提交
34
PageAbility提供命周期回调,开发者可以在`app.js/app.ets`中重写生命周期相关回调函数 。目前`app.js`环境中仅支持onCreate和onDestroy回调,`app.ets`环境支持全量生命周期回调。
G
guyuanzhang 已提交
35

C
caochunlei 已提交
36 37
### 启动模式
ability支持单实例、多实例和指定实例3种启动模式。
C
caochunlei 已提交
38
在config.json中通过launchType配置项,可以配置具体的启动模式,其中:
C
caochunlei 已提交
39 40 41

| 启动模式     | 描述     |说明             |
| ----------- | -------  |---------------- |
42
| standard    | 多实例   | 每次startAbility都会启动一个新的实例 |
C
caochunlei 已提交
43 44 45
| singleton   | 单实例   | 系统中只存在唯一一个实例,startAbility时,如果已存在,则复用系统中的唯一一个实例 |
| specified   | 指定实例 | 运行时由ability内部业务决定是否创建多实例 |

46
缺省情况下是standard模式。
C
caochunlei 已提交
47 48


G
guyuanzhang 已提交
49 50
## 开发指导
### featureAbility接口说明
G
guyuanzhang 已提交
51

G
guyuanzhang 已提交
52
**表1** featureAbility接口介绍
G
guyuanzhang 已提交
53

G
guyuanzhang 已提交
54 55 56 57 58 59
| 接口名                                              | 描述            |
| --------------------------------------------------- | --------------- |
| void startAbility(parameter: StartAbilityParameter) | 启动Ability     |
| Context getContext():                               | 获取应用Context |
| void terminateSelf()                                | 结束Ability     |
| bool hasWindowFocus()                               | 是否获取焦点    |
G
guyuanzhang 已提交
60

Z
zhaoyuan 已提交
61

G
guyuanzhang 已提交
62
### 启动本地PageAbility
Z
zhaoyuan 已提交
63

R
RayShih 已提交
64
**导入模块**
Z
zhaoyuan 已提交
65

R
RayShih 已提交
66 67
```js
  import featureAbility from '@ohos.ability.featureAbility'
Z
zhaoyuan 已提交
68
```
R
RayShih 已提交
69 70

**示例**
Z
zhaoyuan 已提交
71 72

```javascript
R
RayShih 已提交
73 74
  import featureAbility from '@ohos.ability.featureAbility'
  featureAbility.startAbility({
Z
zengyawen 已提交
75 76 77 78 79 80
  want:
  {
    action: "",
    entities: [""],
    type: "",
    options: {
R
RayShih 已提交
81
      // Grant the permission to perform read operations on the URI.
Z
zengyawen 已提交
82
      authReadUriPermission: true,
R
RayShih 已提交
83
      // Grant the permission to perform write operations on the URI.
Z
zengyawen 已提交
84
      authWriteUriPermission: true,
R
RayShih 已提交
85
      // support forwarding the Want result to the ability.
Z
zengyawen 已提交
86
      abilityForwardResult: true,
R
RayShih 已提交
87
      // Enable abiligy continuation.
Z
zengyawen 已提交
88
      abilityContinuation: true,
R
RayShih 已提交
89
      // Specify that a component does not belong to ohos.
Z
zengyawen 已提交
90
      notOhosComponent: true,
R
RayShih 已提交
91
      // Specify that an ability is started.
Z
zengyawen 已提交
92
      abilityFormEnabled: true,
R
RayShih 已提交
93
      // Grant the permission for possible persisting on the URI.
Z
zengyawen 已提交
94
      authPersistableUriPermission: true,
R
RayShih 已提交
95
      // Grant the permission for possible persisting on the prefix URI.
Z
zengyawen 已提交
96
      authPrefixUriPermission: true,
R
RayShih 已提交
97
      // Support distributed scheduling system startup on multiple devices.
Z
zengyawen 已提交
98
      abilitySliceMultiDevice: true,
R
RayShih 已提交
99
      // A service ability is started regardless of whether the host application has been started.
Z
zengyawen 已提交
100
      startForegroundAbility: true,
R
RayShih 已提交
101
      // Install the specified ability if it is not installed.
Z
zengyawen 已提交
102
      installOnDemand: true,
R
RayShih 已提交
103
      // Return the result to the ability slice.
Z
zengyawen 已提交
104
      abilitySliceForwardResult: true,
R
RayShih 已提交
105
      // Install the specified ability with background mode if it is not installed.
Z
zengyawen 已提交
106
      installWithBackgroundMode: true
Z
zhaoyuan 已提交
107
    },
Z
zengyawen 已提交
108 109 110 111 112
    deviceId: "",
    bundleName: "com.example.startability",
    abilityName: "com.example.startability.MainAbility",
    uri: ""
  },
R
RayShih 已提交
113 114
  },
  );
Z
zengyawen 已提交
115
```
R
RayShih 已提交
116 117

`want`参数也可以使用parameters参数,使用key-value的方式输入。
R
RayShih 已提交
118

R
RayShih 已提交
119 120
**示例**

Z
zengyawen 已提交
121
```javascript
R
RayShih 已提交
122 123
  import featureAbility from '@ohos.ability.featureAbility'
  featureAbility.startAbility({
Z
zengyawen 已提交
124 125 126 127 128 129 130 131
    want:
    {
        bundleName: "com.example.startability",
        uri: "",
        parameters: {
            abilityName: "com.example.startability.MainAbility"
        }
    },
R
RayShih 已提交
132 133
  },
  );
Z
zhaoyuan 已提交
134
```
135
### 启动远程PageAbility(当前仅对系统应用开放)
136
>说明:由于DeviceManager的getTrustedDeviceListSync接口仅对系统应用开放,当前启动远程PageAbility仅支持系统应用
Z
zhaoyuan 已提交
137

R
RayShih 已提交
138
**导入模块**
Z
zhaoyuan 已提交
139 140

```
R
RayShih 已提交
141 142
  import featureAbility from '@ohos.ability.featureAbility'
  import deviceManager from '@ohos.distributedHardware.deviceManager';
Z
zhaoyuan 已提交
143 144
```

R
RayShih 已提交
145
**示例**
146
```ts
R
RayShih 已提交
147
  function onStartRemoteAbility() {
148
  console.info('onStartRemoteAbility begin');
149
  let params;
150
  let wantValue = {
151 152 153 154 155 156 157 158 159 160 161 162
    bundleName: 'ohos.samples.etsDemo',
    abilityName: 'ohos.samples.etsDemo.RemoteAbility',
    deviceId: getRemoteDeviceId(),
    parameters: params
  };
  console.info('onStartRemoteAbility want=' + JSON.stringify(wantValue));
  featureAbility.startAbility({
    want: wantValue
  }).then((data) => {
    console.info('onStartRemoteAbility finished, ' + JSON.stringify(data));
  });
  console.info('onStartRemoteAbility end');
R
RayShih 已提交
163
  }
164
```
R
RayShih 已提交
165 166

从DeviceManager获取`deviceId`,具体示例代码如下:
R
RayShih 已提交
167

168
```ts
R
RayShih 已提交
169
  import deviceManager from '@ohos.distributedHardware.deviceManager';
170
  let dmClass;
R
RayShih 已提交
171
  function getRemoteDeviceId() {
172
    if (typeof dmClass === 'object' && dmClass != null) {
173
        let list = dmClass.getTrustedDeviceListSync();
174 175 176 177 178 179 180 181 182
        if (typeof (list) == 'undefined' || typeof (list.length) == 'undefined') {
            console.log("MainAbility onButtonClick getRemoteDeviceId err: list is null");
            return;
        }
        console.log("MainAbility onButtonClick getRemoteDeviceId success:" + list[0].deviceId);
        return list[0].deviceId;
    } else {
        console.log("MainAbility onButtonClick getRemoteDeviceId err: dmClass is null");
    }
R
RayShih 已提交
183
  }
184
```
R
RayShih 已提交
185

186
在跨设备场景下,需要向用户申请数据同步的权限。具体示例代码如下:
R
RayShih 已提交
187

188
```ts
189
  import abilityAccessCtrl from "@ohos.abilityAccessCtrl";
R
RayShih 已提交
190 191
  import bundle from '@ohos.bundle';
  async function RequestPermission() {
192
  console.info('RequestPermission begin');
193
  let array: Array<string> = ["ohos.permission.DISTRIBUTED_DATASYNC"];
194 195 196 197
  let bundleFlag = 0;
  let tokenID = undefined;
  let userID = 100;
  let  appInfo = await bundle.getApplicationInfo('ohos.samples.etsDemo', bundleFlag, userID);
198
  tokenID = appInfo.accessTokenId;
199
  let atManager = abilityAccessCtrl.createAtManager();
200 201
  let requestPermissions: Array<string> = [];
  for (let i = 0;i < array.length; i++) {
202
    let result = await atManager.verifyAccessToken(tokenID, array[i]);
203
    console.info("verifyAccessToken result:" + JSON.stringify(result));
204 205 206 207 208
    if (result == abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
    } else {
      requestPermissions.push(array[i]);
    }
  }
209
  console.info("requestPermissions:" + JSON.stringify(requestPermissions));
210 211 212 213 214
  if (requestPermissions.length == 0 || requestPermissions == []) {
    return;
  }
  let context = featureAbility.getContext();
  context.requestPermissionsFromUser(requestPermissions, 1, (data)=>{
215 216 217 218
    console.info("data:" + JSON.stringify(data));
    console.info("data requestCode:" + data.requestCode);
    console.info("data permissions:" + data.permissions);
    console.info("data authResults:" + data.authResults);
219
  });
220
  console.info('RequestPermission end');
R
RayShih 已提交
221
  }
G
guyuanzhang 已提交
222
```
R
RayShih 已提交
223

G
guyuanzhang 已提交
224
### 生命周期接口说明
R
RayShih 已提交
225

G
guyuanzhang 已提交
226 227 228 229
**表2** 生命周期回调函数介绍

| 接口名       | 描述                                                         |
| ------------ | ------------------------------------------------------------ |
230 231
| onShow()     | Ability由后台不可见状态切换到前台可见状态调用onShow方法,此时用户在屏幕可以看到该Ability |
| onHide()     | Ability由前台切换到后台不可见状态时调用onHide方法,此时用户在屏幕看不到该Ability。 |
G
guyuanzhang 已提交
232 233 234 235 236
| onDestroy()  | 应用退出,销毁Ability对象前调用onDestroy方法,开发者可以在该方法里做一些回收资源、清空缓存等应用退出前的准备工作。 |
| onCreate()   | Ability第一次启动创建Ability时调用onCreate方法,开发者可以在该方法里做一些应用初始化工作。 |
| onInactive() | Ability失去焦点时调用onInactive方法,Ability在进入后台状态时会先失去焦点,再进入后台。 |
| onActive()   | Ability切换到前台,并且已经获取焦点时调用onActive方法。      |

R
RayShih 已提交
237
**示例**
R
RayShih 已提交
238

R
RayShih 已提交
239 240
开发者需要重写`app.js/app.ets`中相关生命周期回调函数,IDE模板默认生成`onCreate()``onDestroy()`方法,其他方法需要开发者自行实现。

G
guyuanzhang 已提交
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
```javascript
export default {
  onCreate() {
    console.info('Application onCreate')
  },
  onDestroy() {
    console.info('Application onDestroy')
  },
  onShow(){
    console.info('Application onShow')
  },
  onHide(){
    console.info('Application onHide')
  },
  onInactive(){
    console.info('Application onInactive')
  },
  onActive(){
    console.info('Application onActive')
  },
}
```
### 开发实例
G
guyuanzhang 已提交
264 265
针对pageAbility开发,有以下示例工程可供参考:

R
RayShih 已提交
266
[DMS](https://gitee.com/openharmony/app_samples/tree/master/ability/DMS)
G
guyuanzhang 已提交
267 268

在本示例中完整展示了启动本地Ability、启动远程Ability的使用方法。