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

G
guyuanzhang 已提交
3
## 概述
4

G
guyuanzhang 已提交
5
### 功能简介
6 7 8 9

PageAbility是具备ArkUI实现的Ability,是开发者具体可见并可以与之交互的Ability实例。开发者通过DevEco Studio创建Ability时,DevEco Studio会自动创建相关模板代码。

PageAbility相关能力通过单独的featureAbility实现,生命周期相关回调则通过`app.js/app.ets`中各个回调函数实现。
Z
zhaoyuan 已提交
10

G
guyuanzhang 已提交
11
### PageAbility的生命周期
Z
zhaoyuan 已提交
12

13
**PageAbility生命周期介绍**(Ability Lifecycle):
Z
zhaoyuan 已提交
14

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

PageAbility生命周期流转如下图所示:
Z
zhaoyuan 已提交
18 19 20 21 22 23

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


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

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

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

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

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

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

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

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

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

C
caochunlei 已提交
40
### 启动模式
41

X
xuchenghua 已提交
42
ability支持单实例和多实例两种启动模式。
43 44

`config.json`中通过launchType配置项,可以配置具体的启动模式,其中:
C
caochunlei 已提交
45

贺念哲 已提交
46 47
**表1** 启动模式介绍

C
caochunlei 已提交
48 49
| 启动模式     | 描述     |说明             |
| ----------- | -------  |---------------- |
50 51
| standard    | 多实例   | 每次startAbility都会启动一个新的实例。 |
| singleton   | 单实例   | 系统中只存在唯一一个实例,startAbility时,如果已存在,则复用系统中的唯一一个实例。 |
C
caochunlei 已提交
52

X
xuchenghua 已提交
53
缺省情况下是singleton模式。
C
caochunlei 已提交
54 55


G
guyuanzhang 已提交
56
## 开发指导
57

G
guyuanzhang 已提交
58
### featureAbility接口说明
G
guyuanzhang 已提交
59

贺念哲 已提交
60
**表2** featureAbility接口介绍
G
guyuanzhang 已提交
61

G
guyuanzhang 已提交
62 63
| 接口名                                              | 描述            |
| --------------------------------------------------- | --------------- |
64 65 66 67
| void startAbility(parameter: StartAbilityParameter) | 启动Ability。    |
| Context getContext():                               | 获取应用Context。 |
| void terminateSelf()                                | 结束Ability。     |
| bool hasWindowFocus()                               | 是否获取焦点。    |
G
guyuanzhang 已提交
68

Z
zhaoyuan 已提交
69

G
guyuanzhang 已提交
70
### 启动本地PageAbility
Z
zhaoyuan 已提交
71

R
RayShih 已提交
72
**导入模块**
Z
zhaoyuan 已提交
73

R
RayShih 已提交
74 75
```js
  import featureAbility from '@ohos.ability.featureAbility'
Z
zhaoyuan 已提交
76
```
R
RayShih 已提交
77 78

**示例**
Z
zhaoyuan 已提交
79 80

```javascript
R
RayShih 已提交
81 82
  import featureAbility from '@ohos.ability.featureAbility'
  featureAbility.startAbility({
83 84 85 86 87 88 89 90 91 92 93
      want: {
          action: "",
          entities: [""],
          type: "",
          deviceId: "",
          bundleName: "com.example.myapplication",
          /* FA模型中abilityName由package + Ability name组成 */
          abilityName: "com.example.entry.secondAbility",
          uri: ""
      }
  });
Z
zengyawen 已提交
94
```
R
RayShih 已提交
95

96
### 启动远程PageAbility(当前仅对系统应用开放)
97 98

>说明:由于DeviceManager的getTrustedDeviceListSync接口仅对系统应用开放,当前启动远程PageAbility仅支持系统应用。
Z
zhaoyuan 已提交
99

R
RayShih 已提交
100
**导入模块**
Z
zhaoyuan 已提交
101 102

```
R
RayShih 已提交
103 104
  import featureAbility from '@ohos.ability.featureAbility'
  import deviceManager from '@ohos.distributedHardware.deviceManager';
Z
zhaoyuan 已提交
105 106
```

R
RayShih 已提交
107
**示例**
108
```ts
R
RayShih 已提交
109
  function onStartRemoteAbility() {
110
  console.info('onStartRemoteAbility begin');
111
  let params;
112
  let wantValue = {
113 114 115 116
      bundleName: 'ohos.samples.etsDemo',
      abilityName: 'ohos.samples.etsDemo.RemoteAbility',
      deviceId: getRemoteDeviceId(),
      parameters: params
117 118 119
  };
  console.info('onStartRemoteAbility want=' + JSON.stringify(wantValue));
  featureAbility.startAbility({
120
      want: wantValue
121
  }).then((data) => {
122
      console.info('onStartRemoteAbility finished, ' + JSON.stringify(data));
123 124
  });
  console.info('onStartRemoteAbility end');
R
RayShih 已提交
125
  }
126
```
R
RayShih 已提交
127 128

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

130
```ts
R
RayShih 已提交
131
  import deviceManager from '@ohos.distributedHardware.deviceManager';
132
  let dmClass;
R
RayShih 已提交
133
  function getRemoteDeviceId() {
134 135 136
      if (typeof dmClass === 'object' && dmClass != null) {
          let list = dmClass.getTrustedDeviceListSync();
          if (typeof (list) == 'undefined' || typeof (list.length) == 'undefined') {
137 138
            console.log("MainAbility onButtonClick getRemoteDeviceId err: list is null");
            return;
139 140 141 142 143 144
          }
          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 已提交
145
  }
146
```
R
RayShih 已提交
147

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

150
```ts
151
  import abilityAccessCtrl from "@ohos.abilityAccessCtrl";
R
RayShih 已提交
152 153
  import bundle from '@ohos.bundle';
  async function RequestPermission() {
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
      console.info('RequestPermission begin');
      let array: Array<string> = ["ohos.permission.DISTRIBUTED_DATASYNC"];
      let bundleFlag = 0;
      let tokenID = undefined;
      let userID = 100;
      let  appInfo = await bundle.getApplicationInfo('ohos.samples.etsDemo', bundleFlag, userID);
      tokenID = appInfo.accessTokenId;
      let atManager = abilityAccessCtrl.createAtManager();
      let requestPermissions: Array<string> = [];
      for (let i = 0;i < array.length; i++) {
          let result = await atManager.verifyAccessToken(tokenID, array[i]);
          console.info("verifyAccessToken result:" + JSON.stringify(result));
          if (result != abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
              requestPermissions.push(array[i]);
          }
169
      }
170 171 172 173 174 175 176 177 178 179 180 181
      console.info("requestPermissions:" + JSON.stringify(requestPermissions));
      if (requestPermissions.length == 0 || requestPermissions == []) {
          return;
      }
      let context = featureAbility.getContext();
      context.requestPermissionsFromUser(requestPermissions, 1, (data)=>{
          console.info("data:" + JSON.stringify(data));
          console.info("data requestCode:" + data.requestCode);
          console.info("data permissions:" + data.permissions);
          console.info("data authResults:" + data.authResults);
      });
      console.info('RequestPermission end');
R
RayShih 已提交
182
  }
G
guyuanzhang 已提交
183
```
R
RayShih 已提交
184

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

贺念哲 已提交
187
**表3** 生命周期回调函数介绍
G
guyuanzhang 已提交
188 189 190

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

R
RayShih 已提交
198
**示例**
R
RayShih 已提交
199

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

G
guyuanzhang 已提交
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
```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')
  },
}
```
224
## 相关实例
225

226
针对PageAbility开发,有以下相关实例可供参考:
G
guyuanzhang 已提交
227

228
- [`DMS`:分布式Demo(ArkTS)(API8)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/monthly_20221018/ability/DMS)