首页 > 编程笔记 > 通用技能 阅读:3

鸿蒙Want用法详解(附带实例)

在 Stage 模型中,Want 是对象间信息传递的载体,可以用于应用组件间的信息传递。而在 FA 模型中,Intent 是与之有相同概念的类。

Want 的使用场景之一是作为 startAbility 的参数,其中包含了指定的启动目标,以及启动时需携带的相关数据,如 bundleName 和 abilityName 字段分别指明目标 Ability 所在应用的包名以及对应包内的 Ability 名称。当 AbilityA 启动 AbilityB 并需要传入一些数据给 AbilityB 时,Want 可以作为一个数据载体将数据传送给 AbilityB,如下图所示:


图 1 Want用法示意图

Want的类型

Want 的类型主要是分为显式和隐式。

1) 显式Want

在启动 Ability 时指定了 abilityName 和 bundleName 的 Want 称为显式 Want。

当有明确处理请求的对象时,通过提供目标 Ability 所在应用的 bundleName,并在 Want 内指定 abilityName 便可启动目标 Ability。显式 Want 通常在启动当前应用开发中某个已知 Ability 时被用到,示例如下:
import { Want } from '@kit.AbilityKit';

let wantInfo: Want = {
    deviceId: '', // deviceId为空,表示本设备
    bundleName: 'com.example.myapplication',
    abilityName: 'FuncAbility',
}

2) 隐式Want

在启动 Ability 时未指定 abilityName 的 Want 称为隐式 Want。

当需要处理的对象不明确时,可以使用隐式 Want,在当前应用中使用其他应用提供的某个能力,而不关心提供该能力的具体应用。隐式 Want 使用 skills 标签来定义需要使用的能力,并由系统匹配声明支持该请求的所有应用来处理请求。

例如,需要打开一个链接的请求时,系统将匹配所有声明支持该请求的应用,然后让用户选择使用哪个应用打开链接:
import { Want } from '@kit.AbilityKit';

let wantInfo: Want = {
    action: 'ohos.want.action.search',
    entities: [ 'entity.system.browsable'],
    uri: 'https://www.test.com:8080/query/student',
    type: 'text/plain',
};
其中,action 表示调用方要执行的通用操作(如查看、分享、应用详情)。在隐式 Want 中,可定义该字段,配合 uri 或 parameters 来表示对数据要执行的操作(如打开并查看该 uri 数据)。例如,当 uri 为一段网址时,action 为 ohos.want.action.viewData 则表示匹配可查看该网址的 Ability。在 Want 内声明 action 字段表示希望被调用方应用支持声明的操作。在被调用方应用配置文件 skills 字段内声明 actions 表示该应用支持声明操作。

常见的 action 包括:
entities 表示目标 Ability 的类别信息(如浏览器、视频播放器),在隐式 Want 中是对 action 的补充。在隐式 Want 中,开发者可定义该字段,用来过滤匹配应用的类别,例如必须是浏览器。在 Want 内声明 entities 字段表示希望被调用方应用属于声明的类别。在被调用方应用配置文件 skills 字段内声明 entities 表示该应用所支持的类别。

常用的 entities 包括:
所有 action 和 entities 都定义在 wantConstant 模块中。

Want的参数及属性

Want 的参数及属性说明如下表所示。

表:Want的参数及属性说明
名称 读写属性 类型 必填 描述
deviceId 只读 string 表示目标 Ability 所在设备 ID。如果未设置该字段,则表明本设备
bundleName 只读 string 表示目标 Ability 所在应用名称
moduleName 只读 string 表示目标 Ability 所属的模块名称
abilityName 只读 string 表示目标 Ability 的名称。如果未设置该字段,则该 Want 为隐式。如果在 Want 中同时指定了 bundleName、moduleName 和 abilityName,则 Want 可以直接匹配到指定的 Ability
uri 只读 string 表示携带的数据,一般配合 type 使用,指明待处理的数据类型。如果在 Want 中指定了 uri,则 Want 将匹配指定的 Uri 信息,包括 scheme、schemeSpecificPart、authority 和 path 信息
type 只读 string 表示携带数据类型,使用 MIME 类型规范。例如“text/plain”“image/*”等
action 只读 string 表示要执行的通用操作(如查看、分享、应用详情)。在隐式 Want 中,可定义该字段,配合 uri 或 parameters 来表示对数据要执行的操作(如打开并查看该 uri 数据)。例如,当uri为一段网址,action 为 ohos.want.action.viewData 则表示匹配可查看该网址的Ability
entities 只读 Array<string> 表示目标 Ability 额外的类别信息(如浏览器、视频播放器),在隐式 Want 中是对 action 的补充。在隐式 Want 中可定义该字段,用来过滤匹配 Ability 类别,如必须是浏览器。例如,在 action 字段的举例中,可存在多个应用声明了支持查看网址的操作,其中有应用为普通社交应用,有的为浏览器应用,可通过 entity.system.browsable 过滤掉非浏览器的其他应用
flags 只读 number 表示处理 Want 的方式。例如通过 wantConstant.Flags.FLAG_ABILITY_CONTINUATION 表示是否以设备间迁移方式启动 Ability
parameters 只读 {[key: string]: any} 此参数用于传递自定义数据,通过用户自定义的值对进行数据填充,具体支持的数据类型如 Want API 所示

Want实例

接下来通过显式 Want 启动应用内一个指定的 Ability 组件。

打开 DevEco Studio,选择一个 Empty Ability 工程模板,创建一个名为“ArkTSWantStartAbility”的工程为演示示例。

1) 新建Ability内页面。初始化工程之后,在原有的代码基础上,需要新建一个页面。在 src/main/ets/pages 目录下,通过右击“New→Page→Empty Page”来新建一个页面,并命名为 Second。

对 Second.ets 文件中的 message 变量值进行修改,最终文件内容如下:
@Entry
@Component
struct Second {
    // 修改变量值为Second
    @State message: string = 'Second';

    build() {
        RelativeContainer() {
            Text(this.message)
                .id('SecondHelloWorld')
                .fontSize(50)
                .fontWeight(FontWeight.Bold)
                .alignRules({
                    center: { anchor: '_container_', align: VerticalAlign.Center },
                    middle: { anchor: '_container_', align: HorizontalAlign.Center }
                })
        }
        .height('100%')
        .width('100%')
    }
}

2) 新建Ability

在原有的代码基础上,需要新建一个 Ability。在 src/main/ets 目录下,右击“New→Ability”新建一个名为“SecondAbility”的 Ability。

创建完成之后,会自动在 module.json5 文件中添加该 Ability 的信息:
{
    "name": "SecondAbility",
    "srcEntry": "./ets/secondability/SecondAbility.ets",
    "description": "$string:SecondAbility_desc",
    "icon": "$media:layered_image",
    "label": "$string:SecondAbility_label",
    "startWindowIcon": "$media:startIcon",
    "startWindowBackground": "$color:start_window_background"
}

此时,在 src/main/ets 目录下会初始化一个 secondability 目录,并在 secondability 目录下生成一个 SecondAbility.ts 文件。修改该文件,将 'pages/Index' 改为 'pages/Second',最终文件内容如下:
onWindowStageCreate(windowStage: window.WindowStage): void {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');

    // 加载second页面
    windowStage.loadContent('pages/Second', (err) => {
        if (err.code) {
            hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
            return;
        }
        hilog.info(0x000, 'testTag', 'Succeeded in loading the content.');
    });
}
上述修改主要是为了当启动 SecondAbility 时,Second 页面能够展示。

3) 使用显式 Want 启动 Ability。在 Index.ets 文件中的 Text 组件上,添加单击事件触发执行启动 Ability。Index.ets 代码修改如下:
// 导入common, Want 从 '@kit.AbilityKit';
import { common, Want } from '@kit.AbilityKit';

@Entry
@Component
struct Index {
    @State message: string = 'Hello World';

    build() {
        RelativeContainer() {
            Text(this.message)
                .id('HelloWorld')
                .fontSize(50)
                .fontWeight(FontWeight.Bold)
                .alignRules({
                    center: { anchor: '_container_', align: VerticalAlign.Center },
                    middle: { anchor: '_container_', align: HorizontalAlign.Center }
                })
                .onClick(this.explicitStartAbility) // 设置单击事件,显示启动Ability
        }
        .height('100%')
        .width('100%')
    }

    // 显示启动Ability
    explicitStartAbility() {
        try {
            // 在启动Ability时指定了abilityName和bundleName
            let want: Want = {
                deviceId: "",
                bundleName: "com.waylau.hmos.arkuwantstartability",
                abilityName: "SecondAbility"
            };

            // 获取UIAbility的上下文信息
            let context = getContext(this) as common.UIAbilityContext;

            // 启动UIAbility实例
            context.startAbility(want);
            console.info('explicit start ability succeed');
        } catch(error) {
            console.info('explicit start ability failed with ${error.code}');
        }
    }
}

4) 运行项目后,初始化界面如下图所示:


图 2 初始化界面

在 Index 页面中,单击“Hello World”文本后,此时启动了 SecondAbility,并展示了 Second 页面,界面效果如下图所示。


图 3 Second页面

相关文章