OpenHarmony开发者论坛

标题: OpenHarmony_Ability框架详解 [打印本页]

作者: Laval社区小助手    时间: 2023-12-4 11:03
标题: OpenHarmony_Ability框架详解
[md]## 详情:[OpenHarmony_Ability框架详解](https://laval.csdn.net/647ed31c762a09416a07f688.html)

## 开发环境

**IDE**:DevEco Studio 3.0 Release(Build Version: 3.0.0.993)

**SDK**:Api Version 8和9

## Ability框架

### 概述

**Ability是应用所具备能力的抽象,也是应用程序的重要组成部分。Ability是系统调度应用的最小单元,是能够完成一个独立功能的组件。一个应用可以包含一个或多个Ability。**

### 类型

**Ability的类型存在差异:**

![](file:///C:/Users/kuangansheng/Desktop/%E8%AF%BE%E7%A8%8B%E6%A1%88%E4%BE%8BFAQ/%E8%AF%BE%E7%A8%8B%E6%A1%88%E4%BE%8BFAQ/%E5%85%AC%E5%BC%80%E8%AF%BE%E7%A8%8B/OpenHarmony_Ability%E6%A1%86%E6%9E%B6%E8%AF%A6%E8%A7%A3/img/Ability%E7%B1%BB%E5%9E%8B.PNG?lastModify=1686033067)

![](https://devpress.csdnimg.cn/5c534dfa66ee4c3490f0c75792e137b0.PNG)

**Ability框架模型具有两种形态:**

* **FA模型**
  **API 8及其更早版本的应用程序只能使用FA模型进行开发。FA模型将Ability分为FA(Feature Ability)和PA(Particle Ability)两种类型,其中其中FA支持PageAbility,PA支持ServiceAbility、DataAbility、以及FormAbility。**
* **Stage模型**
  **从API 9开始,Ability框架引入了Stage模型作为第二种应用框架形态,Stage模型将Ability分为PageAbility和ExtensionAbility两大类,其中ExtensionAbility又被扩展为ServiceExtensionAbility、FormExtensionAbility、DataShareExtensionAbility等一系列ExtensionAbility,以便满足更多的使用场景。**

## 基础用法

### FA模型

#### PageAbility

**PageAbility是具备ArkUI实现的Ability,是开发者具体可见并可以与之交互的Ability实例。开发者通过DevEco Studio创建Ability时,DevEco Studio会自动创建相关模板代码。 PageAbility相关能力通过单独的featureAbility实现,生命周期相关回调则通过app.js/app.ets中各个回调函数实现。**

##### 创建PageAbility

1. **首次创建工程,打开DevEco Studio选择Create Project(如果在已有的工程界面创建新工程,则选择File->New->Create Project),然后选择OpenHarmony下的Empty Ability模板,点击Next进行下一步配置。**

![](file:///C:/Users/kuangansheng/Desktop/%E8%AF%BE%E7%A8%8B%E6%A1%88%E4%BE%8BFAQ/%E8%AF%BE%E7%A8%8B%E6%A1%88%E4%BE%8BFAQ/%E5%85%AC%E5%BC%80%E8%AF%BE%E7%A8%8B/OpenHarmony_Ability%E6%A1%86%E6%9E%B6%E8%AF%A6%E8%A7%A3/img/CreateProject.PNG?lastModify=1686033067)

![](https://devpress.csdnimg.cn/308c62214c7943bfa1609d673ab2e572.PNG)

2. **进入工程配置界面,按默认参数设置即可,点击Finish,工具会自动生成示例代码和相关资源,等待工程创建成功。**

![](file:///C:/Users/kuangansheng/Desktop/%E8%AF%BE%E7%A8%8B%E6%A1%88%E4%BE%8BFAQ/%E8%AF%BE%E7%A8%8B%E6%A1%88%E4%BE%8BFAQ/%E5%85%AC%E5%BC%80%E8%AF%BE%E7%A8%8B/OpenHarmony_Ability%E6%A1%86%E6%9E%B6%E8%AF%A6%E8%A7%A3/img/FAConfig.PNG?lastModify=1686033067)

![](https://devpress.csdnimg.cn/b9187a7bfd774601af7a5d4d299c1f2e.PNG)

3. **工程创建成功后生成一个默认的PageAbility,名为MainAbility。**

![](file:///C:/Users/kuangansheng/Desktop/%E8%AF%BE%E7%A8%8B%E6%A1%88%E4%BE%8BFAQ/%E8%AF%BE%E7%A8%8B%E6%A1%88%E4%BE%8BFAQ/%E5%85%AC%E5%BC%80%E8%AF%BE%E7%A8%8B/OpenHarmony_Ability%E6%A1%86%E6%9E%B6%E8%AF%A6%E8%A7%A3/img/FAMainAbility.PNG?lastModify=1686033067)

![](https://devpress.csdnimg.cn/4c04667ccc48449c9c1a0d8fcb5cbf59.PNG)

4. **如需在工程中创建多个PageAbility,点击File->New->Ability->age Ability即可。**

![](file:///C:/Users/kuangansheng/Desktop/%E8%AF%BE%E7%A8%8B%E6%A1%88%E4%BE%8BFAQ/%E8%AF%BE%E7%A8%8B%E6%A1%88%E4%BE%8BFAQ/%E5%85%AC%E5%BC%80%E8%AF%BE%E7%A8%8B/OpenHarmony_Ability%E6%A1%86%E6%9E%B6%E8%AF%A6%E8%A7%A3/img/FAPageAbility.PNG?lastModify=1686033067)

![](https://devpress.csdnimg.cn/4aaa01ad11214c4c9adabb7e24e2aee6.PNG)

##### featureAbility接口说明

| **接口名**                                               | **描述**              |
| -------------------------------------------------------------- | --------------------------- |
| **void: startAbility(parameter: StartAbilityParameter)** | **启动Ability。**     |
| **Context: getContext():**                               | **获取应用Context。** |
| **void: terminateSelf()**                                | **结束Ability。**     |
| **bool: hasWindowFocus()**                               | **是否获取焦点。**    |

##### 启动PageAbility

**使用featureAbility.startAbility方法可以启动本地设备的PageAbility。**

1. **导入模块**

```
import featureAbility from '@ohos.ability.featureAbility'
```

2. **调用featureAbility.startAbility方法,由该方法的Want传递bundleName和abilityName属性来启动PageAbility。**

* **bundleName:表示包名称。可在config.json中的app字段查看bundleName,或者通过File->roject Structure查看。**
* **abilityName:表示待启动的Ability名称,由config.json中的package字段与abilities字段下的name字段组成。**

```
featureAbility.startAbility({
        want: {
                bundleName: "com.samples.myapplication",
        // FA模型abilityName由config.json中的package + Ability name组成
                abilityName: "com.samples.myapplication.MainAbility"
        }
});
```

#### ServiceAbility

**基于Service模板的Ability(以下简称“Service”),主要用于后台运行任务(如执行音乐播放、文件下载等),但不提供用户UI交互界面。Service可由其他应用或Ability启动。即使用户切换到其他应用,Service仍将在后台继续运行。**

##### 接口说明

**Service中相关生命周期API功能介绍**

| **接口名**                                        | **描述**                                                                                                                       |
| ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| **onStart?(): void**                              | **该方法在创建Service的时候调用,用于Service的初始化。在Service的整个生命周期只会调用一次,调用时传入的Want应为空。**          |
| **onCommand?(want: Want, startId: number): void** | **在Service创建完成之后调用,该方法在客户端每次启动该Service时都会调用,开发者可以在该方法中做一些调用统计、初始化类的操作。** |
| **onConnect?(want: Want): rpc.RemoteObject**      | **在Ability和Service连接时调用。**                                                                                             |
| **onDisconnect?(want: Want): void**               | **在Ability与绑定的Service断开连接时调用。**                                                                                   |
| **onStop?(): void**                               | **在Service销毁时调用。开发者应通过实现此方法来清理资源,如关闭线程、注册的侦听器等。**                                        |

##### 创建与注册Service

1. **在工程中,选择File->New->Ability->Service Ability,点击Finish,成功创建ServiceAbility,默认生成service.ts文件。**

![](file:///C:/Users/kuangansheng/Desktop/%E8%AF%BE%E7%A8%8B%E6%A1%88%E4%BE%8BFAQ/%E8%AF%BE%E7%A8%8B%E6%A1%88%E4%BE%8BFAQ/%E5%85%AC%E5%BC%80%E8%AF%BE%E7%A8%8B/OpenHarmony_Ability%E6%A1%86%E6%9E%B6%E8%AF%A6%E8%A7%A3/img/FAServiceAbility.PNG?lastModify=1686033067)

![](https://devpress.csdnimg.cn/a4d79444da6a4c7094bfb890db9d1351.PNG)

2. **重写Service的生命周期方法,来添加其他Ability请求与ServiceAbility交互时的处理方法。**

```
// service.ts
import hilog from '@ohos.hilog';

export default {
    onStart() {
        hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
        hilog.info(0x0000, 'testTag', '%{public}s', 'ServiceAbility onStart');
    },
    onStop() {
        hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
        hilog.info(0x0000, 'testTag', '%{public}s', 'ServiceAbility onStop');
    },
    onCommand(want, startId) {
        hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
        hilog.info(0x0000, 'testTag', '%{public}s', 'ServiceAbility onCommand');
    },
    onConnect(want) {
        hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
        hilog.info(0x0000, 'testTag', '%{public}s', 'ServiceAbility onConnect');
        return null;
    },
    onDisconnect(want) {
        hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
        hilog.info(0x0000, 'testTag', '%{public}s', 'ServiceAbility OnDisConnect');
    }
};
```

3. **注册Service。FA模型在创建ServiceAbility时已在config.json中自动注册,注册类型type为service,只需手动添加visible字段并设置为true。**

**config.json配置样例**

```
// config.json
"module": {
    ...
    "abilities": [
      ...
      {
        "name": ".ServiceAbility",
        "srcLanguage": "ets",
        "srcPath": "ServiceAbility",
        "icon": "$media:icon",
        "description": "$string:ServiceAbility_desc",
        "type": "service",
        "visible": true
      }
      ...
    ]
    ...
}
```

**Json重要字段**

| **字段名**    | **备注说明**                                                                                   |  |
| ------------------- | ---------------------------------------------------------------------------------------------------- | - |
| **"name"**    | **Ability名称,对应Ability派生的Service类名。**                                                |  |
| **"type"**    | **Ability类型,Service对应的Ability类型为”service“。**                                       |  |
| **"visible"** | **指定能力是否可被其他应用调用,默认值为false,设置为true时,Service才能与其他应用进行调用。** |  |

##### 启动Service

**Ability为开发者提供了startAbility()方法来启动另外一个Ability,因为Service也是Ability的一种,开发者同样可以通过将want传递给该方法来启动Service,通过构造包含bundleName与abilityName的Want对象来设置目标Service信息。**

**启动本地设备Service示例如下:**

```
import featureAbility from '@ohos.ability.featureAbility';

featureAbility.startAbility({
    want:
        {
            bundleName: "com.samples.myapplication",
            // FA模型abilityName由config.json中的package + Ability name组成
            abilityName: "com.samples.myapplication.ServiceAbility",
        }
    }
);
```

**执行上述代码后,Ability将通过startAbility()方法来启动Service。**

* **如果Service尚未运行,则系统会先调用onStart()来初始化Service,再回调Service的onCommand()方法来启动Service。**
* **如果Service正在运行,则系统会直接回调Service的onCommand()方法来启动Service。**

##### 连接Service

**如果Service需要与Page Ability或其他应用的Service Ability进行交互,则须创建用于连接的Connection。Service支持其他Ability通过connectAbility()方法将当前Ability连接到指定ServiceAbility。在使用connectAbility()处理回调时,需要传入目标Service的Want与ConnectOptions远程对象实例。**

**ConnectOptions远程对象实例提供了以下方法:**

* **onConnect():处理连接Service成功的回调。**
* **onDisconnect():处理Service异常死亡的回调。**
* **onFailed():处理连接Service失败的回调。**

**创建连接本地Service回调实例以及连接本地Service的示例如下:**

```
import prompt from '@ohos.prompt';
import featureAbility from '@ohos.ability.featureAbility';
// 导入rpc进程通信模块
import rpc from "@ohos.rpc";

connectService() {
    // ConnectOptions远程对象实例
    let connectOptions = {
        // 连接成功时回调
        onConnect: function onConnectCallback(element, proxy) {
            console.log(`onConnectLocalService onConnectDone element{element}`)
            if (proxy === null) {
                prompt.showToast({
                    message: 'Connect service failed'
                })
                return
            }
            // 携带客户端调用参数的MessageParcel对象
            let data = rpc.MessageParcel.create()
            // 接收应答数据的MessageParcel对象
            let reply = rpc.MessageParcel.create()
            // 本次请求的同异步模式,默认为TF_SYNC同步调用
            let option = new rpc.MessageOption()
            // 将字符串值写入MessageParcel实例
            data.writeString("connect")
            // 以同步模式向服务端发送MessageParcel消息,发送的消息代码为1,同步模式下该接口将等待服务端的响应,直到请求超时,响应的结果在reply中
            proxy.sendRequest(1, data, reply, option).then((result) => {
                console.log(`sendRequest: ${result}`);
                // 客户端以reply从MessageParcel实例中读取服务端处理后的字符串值
                let msg = reply.readString();
                console.log(`sendRequest msg: ${msg}`);
            }).catch((err) => {
                console.log(`sendRequest error: ${err}`);
            });
            prompt.showToast({
                message: "Connect service success"
            })
        },
        // 连接断开时回调
        onDisconnect: function onDisconnectCallback(element) {
            console.log(`onConnectLocalService onDisconnectDone element{element}`)
            prompt.showToast({
                message: "Disconnect service success"
            })
        },
        // 连接失败时回调
        onFailed: function onFailedCallback(code) {
            console.log(`onConnectLocalService onFailed errCode{code}`)
            prompt.showToast({
                message: "Connect local service onFailed"
            })
        }
    }
    // want参数
    let want = {
        bundleName: 'com.samples.myapplication',
        // FA模型abilityName由config.json中的package + Ability name组成
        abilityName: 'com.samples.myapplication.ServiceAbility'
    };
    // 连接本地Service
    featureAbility.connectAbility(want, connectOptions);
}
```

**同时,Service服务端也需要在onConnect()时返回IRemoteObject,从而定义与Service进行通信的接口。OpenHarmony提供了IRemoteObject的默认实现,可以通过继承rpc.RemoteObject来创建自定义的实现类。**

**Service服务端把自身的实例返回给调用侧的代码示例如下:**

```
// service.ts
import rpc from '@ohos.rpc';
import hilog from '@ohos.hilog';

// 实现远程对象,服务提供者必须继承RemoteObject类
class FirstServiceAbilityStub extends rpc.RemoteObject {
    // 用于创建RemoteObject实例的构造函数,参数des为指定接口描述符
    constructor(des: any) {
        super(des)
    }
    // sendRequest请求的响应处理函数,服务端在该函数里处理请求,回复结果
    onRemoteRequest(code, data, reply, option) {
        console.log(`onRemoteRequest called`)
        // 判断客户端发送过来的消息代码是否为1
        if (code === 1) {
            // 从MessageParcel实例中读取由客户端写入的字符串值
            let string = data.readString()
            console.log(`string=${string}`)
            // 将读取的字符串作拆分和排序处理
            let result = Array.from(string).sort().join('')
            console.log(`result=${result}`)
            // 将处理后的字符串值写入MessageParcel实例
            reply.writeString(result)
        } else {
            console.log(`unknown request code`)
        }
        return true;
    }
};

export default {
    onStart() {
        hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
        hilog.info(0x0000, 'testTag', '%{public}s', 'ServiceAbility onStart');
    },
    onStop() {
        hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
        hilog.info(0x0000, 'testTag', '%{public}s', 'ServiceAbility onStop');
    },
    onCommand(want, startId) {
        hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
        hilog.info(0x0000, 'testTag', '%{public}s', 'ServiceAbility onCommand');
    },
    onConnect(want) {
        hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
        hilog.info(0x0000, 'testTag', '%{public}s', 'ServiceAbility onConnect');
        // 返回RemoteObject对象与描述符
        return new FirstServiceAbilityStub('first ts service stub');
    },
    onDisconnect(want) {
        hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
        hilog.info(0x0000, 'testTag', '%{public}s', 'ServiceAbility OnDisConnect');
    }
};
```

#### DataAbility

**基于Data模板的Ability(以下简称“Data”),有助于应用管理其自身和其他应用存储数据的访问,并提供与其他应用共享数据的方法,但不提供用户UI交互界面。Data既可用于同设备不同应用的数据共享,也支持跨设备不同应用的数据共享。**

**Data提供方可以自定义数据的增、删、改、查,以及文件打开等功能,并对外提供这些接口。**

##### 接口说明

**Data中相关生命周期API功能介绍**

| **接口名**                                                                                                                                                   | **描述**                                                                                                                 |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ |
| **onInitialized?(info: AbilityInfo): void**                                                                                                                  | **在Ability初始化调用,通过此回调方法执行RDB等初始化操作。**                                                             |
| **update?(uri: string, valueBucket: rdb.ValuesBucket, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback**<number>**): void**      | **更新数据库中的数据。**                                                                                                 |
| **query?(uri: string, columns: Array**<string>**, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback**<ResultSet>**): void** | **查询数据库中的数据。**                                                                                                 |
| **delete?(uri: string, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback**<number>**): void**                                     | **删除一条或多条数据。**                                                                                                 |
| **normalizeUri?(uri: string, callback: AsyncCallback**<string>**): void**                                                                              | **对uri进行规范化。一个规范化的uri可以支持跨设备使用、持久化、备份和还原等,当上下文改变时仍然可以引用到相同的数据项。** |
| **batchInsert?(uri: string, valueBuckets: Array<rdb.ValuesBucket>, callback: AsyncCallback**<number>**): void**                                        | **向数据库中插入多条数据。**                                                                                             |
| **denormalizeUri?(uri: string, callback: AsyncCallback**<string>**): void**                                                                            | **将一个由normalizeUri生产的规范化URI转换成非规范化的uri。**                                                             |
| **insert?(uri: string, valueBucket: rdb.ValuesBucket, callback: AsyncCallback**<number>**): void**                                                     | **向数据中插入一条数据。**                                                                                               |
| **openFile?(uri: string, mode: string, callback: AsyncCallback**<number>**): void**                                                                    | **打开一个文件。**                                                                                                       |
| **getFileTypes?(uri: string, mimeTypeFilter: string, callback: AsyncCallback<Array**<string>**>): void**                                               | **获取文件的MIME类型。**                                                                                                 |
| **getType?(uri: string, callback: AsyncCallback**<string>**): void**                                                                                   | **获取uri指定数据相匹配的MIME类型。**                                                                                    |
| **executeBatch?(ops: Array**<DataAbilityOperation>**, callback: AsyncCallback<Array**<DataAbilityResult>**>): void**                             | **批量操作数据库中的数据。**                                                                                             |
| **call?(method: string, arg: string, extras: PacMap, callback: AsyncCallback**<acMap>**): void**                                                      | **自定义方法。**                                                                                                         |

##### 创建与注册Data

1. **在工程中,选择File->New->Ability->Data Ability,点击Finish,成功创建DataAbility,默认生成data.ts文件。**

![](file:///C:/Users/kuangansheng/Desktop/%E8%AF%BE%E7%A8%8B%E6%A1%88%E4%BE%8BFAQ/%E8%AF%BE%E7%A8%8B%E6%A1%88%E4%BE%8BFAQ/%E5%85%AC%E5%BC%80%E8%AF%BE%E7%A8%8B/OpenHarmony_Ability%E6%A1%86%E6%9E%B6%E8%AF%A6%E8%A7%A3/img/FADataAbility.PNG?lastModify=1686033067)

![](https://devpress.csdnimg.cn/ab5964d792f6454e9a7eb6e17ce53473.PNG)

2. **在data.ts文件中,实现Data的insert、query、update、delete等相关接口的业务内容,保证能够满足数据库存储业务的基本需求。batchInsert与executeBatch接口在系统中实现遍历逻辑,依赖insert、query、update、delete接口逻辑,来实现数据的批量处理。**

**创建Data示例如下:**

```
// data.ts
import hilog from '@ohos.hilog';
import featureAbility from '@ohos.ability.featureAbility';
// 导入DataAbility谓词相关模块
import dataAbility from '@ohos.data.dataAbility';
// 导入rdb关系数据库模块
import dataRdb from '@ohos.data.rdb';

// 表名
const TABLE_NAME = 'book';
// 库的配置信息:库名称
const STORE_CONFIG = { name: 'book.db' };
// 表结构
const SQL_CREATE_TABLE = 'CREATE TABLE IF NOT EXISTS book(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, introduction TEXT NOT NULL)';
// rdb库对象
let rdbStore: dataRdb.RdbStore = undefined;

export default {
    // 初始化库和表
    onInitialized(abilityInfo) {
        hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
        hilog.info(0x0000, 'testTag', '%{public}s', 'DataAbility onInitialized');
        // 获取应用上下文
        let context = featureAbility.getContext();
        // 获取一个相关的RdbStore,操作关系型数据库
        dataRdb.getRdbStore(context, STORE_CONFIG, 1).then((store) => {
            console.info('DataAbility getRdbStore callback');
            // 执行包含指定参数但不返回值的SQL语句
            store.executeSql(SQL_CREATE_TABLE, null);
            // 把获得的数据库存入本地变量,防止后面多次操作读取创建
            rdbStore = store;
        });
    },
    // 向数据库中插入一条数据
    insert(uri, valueBucket, callback) {
        hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
        hilog.info(0x0000, 'testTag', '%{public}s', 'DataAbility insert');
        rdbStore.insert(TABLE_NAME, valueBucket, callback);
    },
    // 向数据库中插入多条数据
    batchInsert(uri, valueBuckets, callback) {
        hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
        hilog.info(0x0000, 'testTag', '%{public}s', 'DataAbility batchInsert');
        for (let i = 0; i < valueBuckets.length; i++) {
            console.info('DataAbility batch insert i=' + i)
            if (i < valueBuckets.length - 1) {
                rdbStore.insert(TABLE_NAME, valueBuckets, (err: any, num: number) => {
                    console.info('DataAbility batch insert ret=' + num)
                })
            } else {
                rdbStore.insert(TABLE_NAME, valueBuckets, callback)
            }
        }
    },
    // 查询数据库中的数据
    query(uri, columns, predicates, callback) {
        hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
        hilog.info(0x0000, 'testTag', '%{public}s', 'DataAbility query');
        let rdbPredicates = dataAbility.createRdbPredicates(TABLE_NAME, predicates);
        rdbStore.query(rdbPredicates, columns, callback);
    },
    // 更新数据库中的数据
    update(uri, valueBucket, predicates, callback) {
        hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
        hilog.info(0x0000, 'testTag', '%{public}s', 'DataAbility update');
        let rdbPredicates = dataAbility.createRdbPredicates(TABLE_NAME, predicates);
        rdbStore.update(valueBucket, rdbPredicates, callback);
    },
    // 删除一条或多条数据
    delete(uri, predicates, callback) {
        hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
        hilog.info(0x0000, 'testTag', '%{public}s', 'DataAbility delete');
        let rdbPredicates = dataAbility.createRdbPredicates(TABLE_NAME, predicates);
        rdbStore.delete(rdbPredicates, callback);
    }
};
```

3. **注册Data。FA模型在创建DataAbility时已在config.json中自动注册,注册类型type为data,visible字段需手动添加并设置为true。注册后会生成默认权限defPermissions字段,表明调用Data之前须配置这些权限,添加reqPermissions字段设置相应权限。**

**config.json配置样例**

```
"module": {
    "package": "com.samples.myapplication",
    ...
    "abilities": [
        ...
        {
            "name": ".DataAbility",
            "srcLanguage": "ets",
            "srcPath": "DataAbility",
            "icon": "$media:icon",
            "description": "$stringataAbility_desc",
            "type": "data",
            "uri": "dataability://com.samples.myapplication.DataAbility",
            "visible": true
        }
    ],
    ...
    "defPermissions": [
        {
                "name": "com.example.entry.DataAbilityShellProvider.PROVIDER"
            }
    ],
    "reqPermissions": [
        {
                "name": "com.example.entry.DataAbilityShellProvider.PROVIDER"
            }
    ]
    ...
}
```

**Json重要字段**

| **字段名**           | **备注说明**                                                                                        |
| -------------------------- | --------------------------------------------------------------------------------------------------------- |
| **"name"**           | **Ability名称,对应Ability派生的Data类名。**                                                        |
| **"type"**           | **Ability类型,Data对应的Ability类型为”data“。**                                                  |
| **"uri"**            | **通信使用的uri。URL后缀由"package"字段和"name"字段组成。**                                         |
| **"visible"**        | **指定能力是否可被其他应用调用,默认值为false,设置为true时,Data才能与其他应用进行通信传输数据。** |
| **"defPermissions"** | **表示应用程序默认需要的权限,调用者在调用Data之前必须获取相应权限。**                              |

##### 访问Data

**需导入基础模块,以及获取与Data子模块通信的uri字符串。基础模块包括:**

* **@ohos.ability.featureAbility**
* **@ohos.data.dataability**
* **@ohos.data.rdb**

1. **创建工具接口类对象。**

```
import featureAbility from '@ohos.ability.featureAbility';
import dataAbility from '@ohos.data.dataAbility';
import dataRdb from '@ohos.data.rdb';

// 定义数据访问uri常量
// 注意:作为参数传递的uri,比config.json中定义的uri多了一个"/",因为在第二个与第三个"/"中间,存在一个DeviceID的参数
let BASE_URI = "dataability:///com.example.entry.DataAbility";
// 获取dataAbilityHelper,用来协助其他Ability访问DataAbility的工具类。
let DA_HELPER = featureAbility.acquireDataAbilityHelper(BASE_URI);
// 定义表的列名
const COLUMNS = ['id', 'name', 'introduction'];
// 获取谓词
let predicates = new dataAbility.DataAbilityPredicates();
```

2. **构建数据库相关的RDB数据。**

```
// 创建一个BookModel数据模型
export class BookModel {
  id: number
  name: string
  introduction: string

  constructor(id: number, name: string, introduction: string) {
    this.id = id;
    this.name = name;
    this.introduction = introduction;
  }
}

//初始化测试数据
export function initValuesBuckets() {
  let valuesBuckets = [
    { 'name': 'Book name1', 'introduction': 'Book introduction1' },
    { 'name': 'Book name2', 'introduction': 'Book introduction2' },
    { 'name': 'Book name3', 'introduction': 'Book introduction3' }];
  return valuesBuckets;
}

// 将数据转换为BookModel数组,用于处理DA_HELPER返回的数据。
// 获取一个BookModel的数据列表
export function getListFromResultSet(resultSet) {
  let bookList = [];
  for (let i = 0;i < resultSet.rowCount; i++) {
    //按照构造函数进行封装
    let book = new BookModel(
        resultSet.getDouble(resultSet.getColumnIndex('id'))
      , resultSet.getString(resultSet.getColumnIndex('name'))
      , resultSet.getString(resultSet.getColumnIndex('introduction')));
    //添加到列表中
    bookList.push(book);
  }
  return bookList;
}

let valuesBucket = { 'name': 'Book name', 'introduction': 'Book introduction' };
let valuesBuckets = [
    { 'name': 'Book name1', 'introduction': 'Book introduction1' },
    { 'name': 'Book name2', 'introduction': 'Book introduction2' },
    { 'name': 'Book name3', 'introduction': 'Book introduction3' }
];
```

3. **调用insert方法向指定的Data子模块插入数据。**

```
let bookList: Array<BookModel> = [];

let valuesBucket = { name: 'Book name', introduction: 'Book introduction' };
DA_HELPER.insert(BASE_URI, valuesBucket, predicates).then((data) => {
    console.log("DAHelper insert result: " + data);
    bookList.push({ id: data, name: 'Book name', introduction: 'Book introduction' });
}).catch((err) => {
    console.log('DAHelper insert fail: ' + err);
});
```

4. **调用delete方法删除Data子模块中指定的数据。**

```
let book: BookModel = null;

predicates.equalTo('id', book.id);
DA_HELPER.delete(BASE_URI, predicates).then((data) => {
    console.log("DAHelper delete result: " + data);
}).catch((err) => {
    console.log('DAHelper delete fail: ' + err);
});
```

5. **调用update方法更新指定Data子模块中的数据。**

```
let book: BookModel = null;

predicates.equalTo('id', book.id);
let valuesBucket = {
    'name': book.name,
    'introduction': book.introduction
};
DA_HELPER.update(BASE_URI, valuesBucket, predicates).then((data) => {
    console.log("DAHelper update result: " + data);
}).catch((err) => {
    console.log('DAHelper update fail: ' + err);
});
```

6. **调用query方法在指定的Data子模块中查找数据。**

```
let bookList: Array<BookModel> = [];

//根据名字或介绍模糊匹配
predicates.contains('name', 'Book name1')
        .or()
    .contains('introduction', 'Book introduction1');
DA_HELPER.query(BASE_URI, COLUMNS, predicates).then((data) => {
    console.log("DAHelper query result: " + data);
    bookList = getListFromResultSet(resultSet);
}).catch((err) => {
    console.log('DAHelper query fail: ' + err);
});
```

7. **调用batchInsert方法向指定的数据子模块批量插入数据。**

```
let valuesBuckets = initValuesBuckets();

DA_HELPER.batchInsert(BASE_URI, valuesBuckets, predicates).then((data) => {
    console.log("DAHelper batchInsert result: " + data);
}).catch((err) => {
    console.log('DAHelper batchInsert fail: ' + err);
});
```

### Stage模型

#### Ability开发指导

**开发Stage模型应用时,需要在module.json5和app.json配置文件中对应用的包结构进行声明。基于Stage模型的Ability应用开发,主要涉及如下功能逻辑:**

* **创建支持使用屏幕浏览及人机交互的Ability应用,包括实现Ability的生命周期、获取Ability配置信息、向用户申请授权及环境变化通知等场景。**
* **启动Ability应用,包括相同设备启动Ability、跨设备启动Ability以及指定页面启动Ability等场景。**
* **通用组件Call功能。**
* **连接、断开ServiceExtensionAbility。**
* **应用迁移。**

##### 创建Ability

1. **点击Create Project,选择OpenHarmony下的Empty Ability模板,点击Next进行下一步配置。在工程配置项中, "Compile API"选择"9","Model"默认为"Stage",其他参数可保持默认设置。点击Finish,工具会自动生成示例代码和相关资源,等待工程创建成功。**

![](file:///C:/Users/kuangansheng/Desktop/%E8%AF%BE%E7%A8%8B%E6%A1%88%E4%BE%8BFAQ/%E8%AF%BE%E7%A8%8B%E6%A1%88%E4%BE%8BFAQ/%E5%85%AC%E5%BC%80%E8%AF%BE%E7%A8%8B/OpenHarmony_Ability%E6%A1%86%E6%9E%B6%E8%AF%A6%E8%A7%A3/img/StageConfig.PNG?lastModify=1686033067)

![](https://devpress.csdnimg.cn/ae4c3191f0884569a56aea57383dcbf4.PNG)

2. **工程创建成功后生成默认的Ability,名为MainAbility。**

![](file:///C:/Users/kuangansheng/Desktop/%E8%AF%BE%E7%A8%8B%E6%A1%88%E4%BE%8BFAQ/%E8%AF%BE%E7%A8%8B%E6%A1%88%E4%BE%8BFAQ/%E5%85%AC%E5%BC%80%E8%AF%BE%E7%A8%8B/OpenHarmony_Ability%E6%A1%86%E6%9E%B6%E8%AF%A6%E8%A7%A3/img/StageAbility.PNG?lastModify=1686033067)

![](https://devpress.csdnimg.cn/4e37d88a84c54441a15ce8172445f40b.PNG)

##### 启动Ability

**应用可以通过this.context获取Ability实例的上下文,进而使用AbilityContext中的StartAbility相关接口启动Ability。启动Ability由Wan传递bundleName和abilityName属性,通过callback形式或promise形式实现。**

* **bundleName:表示包名称。可在AppScope->app.json5中查看bundleName,或者通过File->roject Structure查看。**
* **abilityName:表示待启动的Ability名称。**

**启动本地设备Ability示例如下:**

```
// MainAbility.ts
import hilog from '@ohos.hilog';
import Ability from '@ohos.application.Ability';
import Window from '@ohos.window';

export default class MainAbility extends Ability {
    ...
    onWindowStageCreate(windowStage: Window.WindowStage) {
        // Main window is created, set main page for this ability
        hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
        hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
      
        // want参数配置
                let want = {
            bundleName: "com.samples.myapplication",
            abilityName: "MainAbility"
        };
        // 拉起指定的Ability
        this.context.startAbility(want).then((data) => {
            console.log("Succeed to start ability with data: " + JSON.stringify(data))
        }).catch((error) => {
            console.error("Failed to start ability with error: " + JSON.stringify(error))
        });

        windowStage.loadContent('pages/index', (err, data) => {
            if (err.code) {
                hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.ERROR);
                hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
                return;
            }
            hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
            hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
        });
    }
        ...
};
```

#### ExtensionAbility机制

**ExtensionAbility是Stage模型中新增的扩展组件的基类,一般用于处理无界面的任务,生命周期较简单,没有前后台生命周期。**

**不同于用于页面展示的Ability,ExtensionAbility提供的是一种受限的服务运行环境。ExtensionAbility具有如下特点:**

* **独立于主进程的单独进程运行,与主进程无IPC,共享一个存储沙箱。**
* **独立的Context提供基于业务场景的api能力。**
* **由系统触发创建,应用不能直接创建。**
* **ExtensionAbility和进程的生命周期受系统管理。**

#### ServiceExtensionAbility开发指导

**ServiceExtensionAbility是ExtensionAbility的扩展类。开发者可以自定义类继承ServiceExtensionAbility,通过重写基类中相关生命周期方法,来做初始化、连接中、断开连接时相关业务逻辑操作。**

##### 接口说明

**ServiceExtensionAbility中相关生命周期API功能介绍**

| **接口名**                                       | **描述**                                                                                                                                                               |
| ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **onCreate(want: Want): void**                   | **首次调用startAbility、connectAbility时触发,执行初始化业务逻辑操作。**                                                                                               |
| **onRequest(want: Want, startId: number): void** | **每次调用startAbility拉起服务都会触发,首次调用时startId为1,重复调用时startId会递增。**                                                                              |
| **onConnect(want: Want): rpc.RemoteObject**      | **调用connectAbility拉起服务时触发,重复调用不会再次触发,除非调用disconnectAbility解除绑定后再调用;onConnect返回一个进程通信类RemoteObject,用于和客户端进行通信。** |
| **onDestroy(): void**                            | **调用停止当前Ability的接口terminateSelf时触发,执行资源清理等操作。**                                                                                                 |
| **onDisconnect(want: Want): void**               | **调用disconnectAbility断开服务连接时触发,Extension如果是用connectAbility拉起的,并且已经没有其他应用绑定这个Extension,则会触发onDestroy生命周期销毁组件。**         |

##### 创建与注册ServiceExtensionAbility

1. **在ets目录下选择New->Directory创建ServiceExtAbility目录,然后在ServiceExtAbility目录选择New->ts File创建ServiceExtAbility.ts文件。**

![](file:///C:/Users/kuangansheng/Desktop/%E8%AF%BE%E7%A8%8B%E6%A1%88%E4%BE%8BFAQ/%E8%AF%BE%E7%A8%8B%E6%A1%88%E4%BE%8BFAQ/%E5%85%AC%E5%BC%80%E8%AF%BE%E7%A8%8B/OpenHarmony_Ability%E6%A1%86%E6%9E%B6%E8%AF%A6%E8%A7%A3/img/StageServiceExtensionAbility.PNG?lastModify=1686033067)

![](https://devpress.csdnimg.cn/227bc78438034d08b4585386035ef074.PNG)

2. **在ServiceExtAbility.ts文件中自定义类继承ServiceExtensionAbility,重写基类回调函数。**

> **说明:'@ohos.application.ServiceExtensionAbility'模块从SDK 3.2.5.5版本起,被提取到了full-sdk当中,使用时需手动下载并安装full-sdk。**

```
// ServiceExtAbility.ts
import ServiceExtensionAbility from '@ohos.application.ServiceExtensionAbility';

export default class ServiceExtAbility extends ServiceExtensionAbility {
    onCreate(want) {
        console.log(`onCreate, want: ${want.abilityName}`);
    }
    onRequest(want, startId) {
        console.log(`onRequest, want: ${want.abilityName}`);
    }
    onConnect(want) {
        console.log(`onConnect , want: ${want.abilityName}`);
        return null;
    }
    onDisconnect(want) {
        console.log(`onDisconnect, want: ${want.abilityName}`);
    }
    onDestroy() {
        console.log(`onDestroy`);
    }
}
```

3. **注册ServiceExtensionAbility。在配置文件module.json5中进行注册,手动添加"extensionAbilities"配置项,将注册类型type设置为service。**

**module.json5配置样例**

```
"module": {
    ...
    "extensionAbilities": [
        {
                "name": "ServiceExtAbility",
            "srcEntrance": "./ets/ServiceExtAbility/ServiceExtAbility.ts",
                "icon": "$media:icon",
                "description": "service",
                "type": "service",
                "visible": true   
            }
    ]
    ...
}
```

##### 启动ServiceExtensionAbility

**应用通过this.context获取Ability实例的上下文,调用startAbility()方法来启动本地ServiceExtensionAbility,该方法的Want传递bundleName和abilityName属性。将this.context挂载到全局对象globalThis上,用于外部自定义方法调用AbilityContext中的startAbility接口。**

**启动本地设备ServiceExtensionAbility示例如下:**

```
// index.ets
@Entry
@Component
struct Index {
    private context = getContext(this) as any;

    startService() {
        // want参数配置
        let want = {
                      bundleName: "com.samples.myapplication",
                      abilityName: "ServiceExtAbility"
            };
        // 拉起指定的ServiceExtensionAbility
        this.context.startAbility(want).then((data) => {
            console.log(`startAbility success: ${JSON.stringify(data)}`);
        }).catch((error) => {
            console.error(`startAbility failed: ${JSON.stringify(error)}`);
        })
    }

    build() {
        ...
    }
}
```

##### 连接ServiceExtensionAbility

**由this.context获取Ability实例的上下文,调用connectAbility方法连接本地ServiceExtensionAbility,由该方法的Want传递连接目标的bundleName和abilityName属性,ConnectOptions远程对象实例提供onConnect()、onDisconnect()和onFailed()方法,用于监听不同连接状态并回调。**

**创建连接本地ServiceExtensionAbility回调实例以及连接本地ServiceExtensionAbility的示例如下:**

```
import prompt from '@ohos.prompt';
// 导入rpc进程通信模块
import rpc from '@ohos.rpc';

connectService() {
    // ConnectOptions远程对象实例
    let connectOptions = {
        // 连接成功时回调
        onConnect: function onConnectCallback(element, proxy) {
            console.log(`onConnectLocalService onConnectDone element{element} proxy{proxy}`);
            if (proxy === null) {
                prompt.showToast({
                    message: 'Connect service failed'
                })
                return;
            }
            // 携带客户端调用参数的MessageParcel对象
            let data = rpc.MessageParcel.create();
            // 接收应答数据的MessageParcel对象
            let reply = rpc.MessageParcel.create();
            // 本次请求的同异步模式,默认为TF_SYNC同步调用
            let option = new rpc.MessageOption();
            // 将两个整数值写入MessageParcel实例
            data.writeInt(100);
            data.writeInt(200);
            // 以同步模式向服务端发送MessageParcel消息,发送的消息代码为1,同步模式下该接口将等待服务端的响应,直到请求超时,响应的结果在reply中
            proxy.sendRequest(1, data, reply, option).then((result) => {
                console.log(`sendRequest: ${result}`);
                // 客户端以reply从MessageParcel实例中读取服务端处理后的整数值
                let msg = reply.readInt();
                console.log(`sendRequest msg: ${msg}`);
            }).catch((err) => {
                console.log(`sendRequest error: ${err}`);
            });
            prompt.showToast({
                message: "Connect service success"
            })
        },
        // 连接断开时回调
        onDisconnect: function onDisconnectCallback(element) {
            console.log(`onConnectLocalService onDisconnectDone element{element}`);
            prompt.showToast({
                message: "Disconnect service success"
            })
        },
        // 连接失败时回调
        onFailed: function onFailedCallback(code) {
            console.log(`onConnectLocalService onFailed errCode{code}`);
            prompt.showToast({
                message: "Connect local service onFailed"
            })
        }
    }
    // want参数配置
    let want = {
        bundleName: 'com.samples.myapplication',
        abilityName: 'ServiceExtAbility'
    };
    // 连接指定的ServiceExtensionAbility
    this.context.connectAbility(want, connectOptions);
}
```

**ServiceExtensionAbility服务端通过继承rpc.RemoteObject来创建自定义的实现类StubTest,在onConnect()中返回RemoteObject对象与描述符参数。在StubTest类中调用onRemoteRequest()方法响应客户端发送的请求,并对数据作处理。**

**Service服务端把自身的实例返回给调用侧的代码示例如下:**

```
// ServiceExtAbility.ts
import ServiceExtensionAbility from '@ohos.application.ServiceExtensionAbility';
import rpc from '@ohos.rpc';

// 实现远程对象,服务提供者必须继承RemoteObject类
class StubTest extends rpc.RemoteObject {
    // 用于创建RemoteObject实例的构造函数,参数des为指定接口描述符
    constructor(des) {
        super(des);
    }
    // sendRequest请求的响应处理函数,服务端在该函数里处理请求,回复结果
    onRemoteRequest(code, data, reply, option) {
        console.log(`onRemoteRequest`);
        // 判断客户端发送过来的消息代码是否为1
        if (code === REQUEST_VALUE) {
            // 从MessageParcel实例中读取由客户端写入的整数值
            let dataFirst = data.readInt();
            let dataSecond = data.readInt();
            // 将读取的整数值相加并写入MessageParcel实例
            reply.writeInt(dataFirst + dataSecond);
            console.log(`onRemoteRequest: dataFirst: ${dataFirst}, dataSecond: ${dataSecond}`);
        }
        return true;
    }
}

export default class ServiceExtAbility extends ServiceExtensionAbility {
    onCreate(want) {
        console.log(`onCreate, want: ${want.abilityName}`);
    }
    onRequest(want, startId) {
        console.log(`onRequest, want: ${want.abilityName}`);
    }
    onConnect(want) {
        console.log(`onConnect , want: ${want.abilityName}`);
        // 返回RemoteObject对象与描述符
        return new StubTest("test");
    }
    onDisconnect(want) {
        console.log(`onDisconnect, want: ${want.abilityName}`);
    }
    onDestroy() {
        console.log(`onDestroy`);
    }
}
```

## Ability间的跳转

### 应用场景描述

**实现Ability之间的跳转将调用startAbility()方法,此方法根据want参数传递Abillity名称,拉起指定的Ability,达到跳转效果。**

> **说明:Ability跳转效果需在设备上验证。**

### FA模型Ability跳转

1. **在工程中,选择File->New->Ability->age Ability,新建一个PageAbility命名为MainAbilitySecond,并在其pages目录选择New->age新建second.ets页面。目录结构如下:**

![](https://devpress.csdnimg.cn/5e20b97440024f66a027ccaca025dc09.PNG)

2. **在MainAbility/pages/index.ets中导入featureAbility模块。**

```
import featureAbility from '@ohos.ability.featureAbility';
```

3. **在MainAbility/pages/index.ets页面添加Button组件,给Butom添加文本、样式和点击事件,在点击事件中调用featureAbility.startAbility拉起指定的Ability实现跳转。startAbility中的want参数主要传递bundleName和abilityName,在want中添加parameters参数,设置路由url为指定页面,点击Button按钮即可跳转到MainAbilitySecond的指定页面。**

> **说明:want中如果不添加parameters参数,则默认指向Ability的index页面。**

```
// MainAbility/pages/index.ets
import featureAbility from '@ohos.ability.featureAbility';

@Entry
@Component
struct Index {
  build() {
    Row() {
      Column() {
        Button() {
          Text('to MainAbilitySecond')
            .fontSize(25)
            .fontWeight(FontWeight.Bolder)
        }
        .height(60)
        .onClick(() => {
          let parameter = {
            want: {
              bundleName: "com.samples.myapplication",
              // FA模型abilityName由config.json中的package + Ability name组成
              abilityName: "com.samples.myapplication.MainAbilitySecond",
              parameters: {
                url: 'pages/second'
              }
            }
          }
          featureAbility.startAbility(parameter).then((data) => {
            console.info('startAbility successful. Data: ' + JSON.stringify(data))
          }).catch((error) => {
            console.error('startAbility failed. Cause: ' + JSON.stringify(error))
          })
        })
      }
      .width('100%')
    }
    .height('100%')
  }
}
```

### Stage模型Ability跳转

1. **在工程中,选择File->New->Ability,新建一个Ability命名为MainAbilitySecond,在pages目录选择New->age新建second.ets。目录结构如下:**

![](https://devpress.csdnimg.cn/e306ae80ab0c4d5fb95d84ce08e75185.PNG)

2. **将MainAbilitySecond.ts页面中loadContent方法加载的主页面改为pages/second,与MainAbility中加载的index主页面区分开。**

```
// MainAbilitySecond.ts
import hilog from '@ohos.hilog';
import Ability from '@ohos.application.Ability'
import Window from '@ohos.window'

export default class MainAbilitySecond extends Ability {
    ...
    onWindowStageCreate(windowStage: Window.WindowStage) {
        // Main window is created, set main page for this ability
        hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
        hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
      
        // 默认指向pages/index,这里修改为pages/second
        windowStage.loadContent('pages/second', (err, data) => {
            if (err.code) {
                hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.ERROR);
                hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
                return;
            }
            hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
            hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
        });
    }
        ...
}
```

3. **在MainAbility/pages/index.ets页面添加Button组件,给Butom添加文本、样式和点击事件,创建context对象获取应用上下文, 并调用startAbility拉起指定的Ability实现跳转。其中startAbility的want参数传递bundleName和abilityName。**

```
// MainAbility/pages/index.ets
@Entry
@Component
struct Index {
  private context = getContext(this) as any;

  build() {
    Row() {
      Column() {
        Button() {
          Text('to MainAbilitySecond')
            .fontSize(25)
            .fontWeight(FontWeight.Bolder)
        }
        .height(60)
        .onClick(() => {
          let want = {
            bundleName: "com.samples.myapplication",
            abilityName: "MainAbilitySecond"
          }
          this.context.startAbility(want).then((data) => {
            console.info('startAbility successful. Data: ' + JSON.stringify(data))
          }).catch((error) => {
            console.error('startAbility failed. Cause: ' + JSON.stringify(error))
          })
        })
      }
      .width('100%')
    }
    .height('100%')
  }
}
```

## Ability生命周期

### 生命周期差异对比

**FA模型与Stage模型的Ability生命周期存在差异:**

![](file:///C:/Users/kuangansheng/Desktop/%E8%AF%BE%E7%A8%8B%E6%A1%88%E4%BE%8BFAQ/%E8%AF%BE%E7%A8%8B%E6%A1%88%E4%BE%8BFAQ/%E5%85%AC%E5%BC%80%E8%AF%BE%E7%A8%8B/OpenHarmony_Ability%E6%A1%86%E6%9E%B6%E8%AF%A6%E8%A7%A3/img/%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F.PNG?lastModify=1686033067)

### 生命周期接口说明

#### FA模型生命周期回调函数

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

#### Stage模型生命周期回调函数

| **接口名**                                                         | **描述**                                                                                                        |
| ------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- |
| **onCreate(want: Want, param: AbilityConstant.LaunchParam): void** | **Ability生命周期回调,Ability启动时被调用。**                                                                  |
| **onWindowStageCreate(windowStage: window.WindowStage): void**     | **Ability生命周期回调,创建window stage时被调用,应用开发者可通过window.WindowStage的接口执行页面加载等操作。** |
| **onForeground(): void**                                           | **Ability生命周期回调,Ability切换至前台时被调用。**                                                            |
| **onBackground(): void**                                           | **Ability生命周期回调,Ability切换至后台时被调用。**                                                            |
| **onWindowStageDestroy(): void**                                   | **Ability生命周期回调,销毁window stage时被调用。**                                                             |
| **onDestroy(): void**                                              | **Ability生命周期回调,Ability销毁时被调用。**                                                                  |

## Ability启动模式

### FA模型启动模式

**FA模型Ability支持单实例和多实例两种启动模式,在config.json中通过launchType配置项,配置具体的启动模式;如果不配置,则默认为standard模式。**

| **启动模式**  | **描述**   | **说明**                                                                               |
| ------------------- | ---------------- | -------------------------------------------------------------------------------------------- |
| **singleton** | **单实例** | **系统中只存在唯一一个实例,startAbility时,如果已存在,则复用系统中的唯一一个实例。** |
| **standard**  | **多实例** | **每次startAbility调用都会启动一个新的实例。**                                         |

### Stage模型启动模式

**Stage模型Ability支持单实例、多实例和指定实例3种启动模式,在module.json5中默认没有launchType配置项,需手动添加;如果不添加,则默认为singleton模式。**

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

**module.json5示例:**

```
{
  "module": {
    "abilities": [
      {
        ...
        "launchType": "standard"
        ...
      }
    ]
  }
}
```

## 参考文献

**[1] OpenHarmony Ability开发. **[https://gitee.com/openharmony/do ... ication-dev/ability](https://gitee.com/openharmony/do ... ity?login=from_csdn)

**[2] OpenHarmony接口开发. **[https://gitee.com/openharmony/do ... xtension-ability.md](https://gitee.com/openharmony/do ... .md?login=from_csdn)
[/md]




欢迎光临 OpenHarmony开发者论坛 (https://forums.openharmony.cn/) Powered by Discuz! X3.5