fa-pageability.md 9.7 KB
Newer Older
W
wusongqing 已提交
1 2 3 4
# Page Ability Development

## Overview
### Concepts
W
wusongqing 已提交
5
The Page ability implements the ArkUI and provides the capability of interacting with users. When you create an ability in the integrated development environment (IDE), the IDE automatically creates template code. The capabilities related to the Page ability are implemented through the **featureAbility**, and the lifecycle callbacks are implemented through the callbacks in **app.js/app.ets**.
W
wusongqing 已提交
6 7 8

### Page Ability Lifecycle

W
wusongqing 已提交
9
**Ability lifecycle**
W
wusongqing 已提交
10

W
wusongqing 已提交
11 12 13
The Page ability lifecycle is a general term for all states of a Page ability, such as **INACTIVE**, **ACTIVE**, and **BACKGROUND**.

The following figure shows the lifecycle state transition of the Page ability.
W
wusongqing 已提交
14 15 16 17 18 19

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


Description of ability lifecycle states:

W
wusongqing 已提交
20
  - **UNINITIALIZED**: The Page ability is not initialized. This is a temporary state. A Page ability changes directly to the **INITIAL** state upon its creation.
W
wusongqing 已提交
21

W
wusongqing 已提交
22
  - **INITIAL**: This state refers to the initial or stopped state. The Page ability in this state is not running. The Page ability enters the **INACTIVE** state after it is started.
W
wusongqing 已提交
23 24 25 26 27

  - **INACTIVE**: The ability is visible but does not gain focus.

  - **ACTIVE**: The ability runs in the foreground and gains focus.

W
wusongqing 已提交
28
  - **BACKGROUND**: The Page ability returns to the background. After being re-activated, the Page ability enters the **ACTIVE** state. After being destroyed, the Page ability enters the **INITIAL** state.
W
wusongqing 已提交
29

30
**The following figure shows the relationship between lifecycle callbacks and lifecycle states of the Page ability.**
W
wusongqing 已提交
31 32 33

![fa-pageAbility-lifecycle](figures/fa-pageAbility-lifecycle.png)

34
You can override the lifecycle callbacks provided by the Page ability in the **app.js/app.ets** file. Currently, the **app.js** file provides only the **onCreate** and **onDestroy** callbacks, and the **app.ets** file provides the full lifecycle callbacks.
W
wusongqing 已提交
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

## Development Guidelines
### Available APIs

**Table 1** APIs provided by featureAbility

| API                                             | Description           |
| --------------------------------------------------- | --------------- |
| void startAbility(parameter: StartAbilityParameter) | Starts an ability.    |
| Context getContext():                               | Obtains the application context.|
| void terminateSelf()                                | Terminates the ability.    |
| bool hasWindowFocus()                               | Checks whether the ability gains focus.   |


### Starting a Local Page Ability

51
**Modules to Import**
W
wusongqing 已提交
52

53 54
```js
  import featureAbility from '@ohos.ability.featureAbility'
W
wusongqing 已提交
55
```
56 57

**Example**
W
wusongqing 已提交
58 59

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

W
wusongqing 已提交
104
You can also include **parameters** in the **want** parameter and set its value in the key-value format.
W
wusongqing 已提交
105

106 107
**Example**

W
wusongqing 已提交
108
```javascript
109 110
  import featureAbility from '@ohos.ability.featureAbility'
  featureAbility.startAbility({
W
wusongqing 已提交
111 112 113 114 115 116 117 118
    want:
    {
        bundleName: "com.example.startability",
        uri: "",
        parameters: {
            abilityName: "com.example.startability.MainAbility"
        }
    },
119 120
  },
  );
W
wusongqing 已提交
121
```
122 123
### Starting a Remote Page Ability (Applying only to System Applications)
>Note: The **getTrustedDeviceListSync** API of the **DeviceManager** class is open only to system applications. Therefore, remote Page ability startup applies only to system applications.
W
wusongqing 已提交
124

125
**Modules to Import**
W
wusongqing 已提交
126 127

```
128 129
  import featureAbility from '@ohos.ability.featureAbility'
  import deviceManager from '@ohos.distributedHardware.deviceManager';
W
wusongqing 已提交
130 131
```

132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
**Example**
```ts
  function onStartRemoteAbility() {
  console.info('onStartRemoteAbility begin');
  let params;
  let wantValue = {
    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');
  }
```
W
wusongqing 已提交
152

153
Obtain **deviceId** from **DeviceManager**. The sample code is as follows:
W
wusongqing 已提交
154

155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
```ts
  import deviceManager from '@ohos.distributedHardware.deviceManager';
  let dmClass;
  function getRemoteDeviceId() {
    if (typeof dmClass === 'object' && dmClass != null) {
        let list = dmClass.getTrustedDeviceListSync();
        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");
    }
  }
W
wusongqing 已提交
171
```
172 173

In the cross-device scenario, the application must also apply for the data synchronization permission from end users. The sample code is as follows:
W
wusongqing 已提交
174

175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
```ts
  import abilityAccessCtrl from "@ohos.abilityAccessCtrl";
  import bundle from '@ohos.bundle';
  async function RequestPermission() {
  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) {
    } else {
      requestPermissions.push(array[i]);
    }
  }
  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');
  }
```

W
wusongqing 已提交
211
### Lifecycle APIs
W
wusongqing 已提交
212

213
**Table 2** Lifecycle callbacks
W
wusongqing 已提交
214 215 216

| API      | Description                                                        |
| ------------ | ------------------------------------------------------------ |
217 218 219 220 221 222 223 224
| onShow()     | Called when the ability is switched from the background to the foreground. In this case, the ability is visible to users.|
| onHide()     | Called when the ability is switched from the foreground to the background. In this case, the ability is invisible.|
| onDestroy()  | Called when the ability is destroyed. In this callback, you can make preparations for app exit, such as recycling resources and clearing the cache.|
| onCreate()   | Called when the ability is created for the first time. You can initialize the application in this callback.|
| onInactive() | Called when the ability loses focus. An ability loses focus before entering the background state.|
| onActive()   | Called when the ability is switched to the foreground and gains focus.     |

**Example**
W
wusongqing 已提交
225

226 227
You need to override the lifecycle callbacks in **app.js/app.ets**. The IDE template generates **onCreate()** and **onDestroy()** by default. You need to override the other callbacks.

W
wusongqing 已提交
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252
```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')
  },
}
```
### Development Example
The following sample is provided to help you better understand how to develop a Page ability:

253
[DMS](https://gitee.com/openharmony/app_samples/tree/master/ability/DMS)
W
wusongqing 已提交
254 255

This sample describes how to start a local ability and remote ability.