一、背景

在鸿蒙开发中Stage模型提供了“信息传递载体Want”,整理总结下加深理解

二、概念

2.1、Want是什么

Want是一种对象,用于在应用组件之间传递信息,最常见的使用场景是作为startAbility()方法的参数

例如,当UIAbilityA需要启动UIAbilityB并向UIAbilityB传递一些数据时,可以使用Want作为一个载体,将数据传递给UIAbilityB。

以“快递单 + 快递包裹”来类比Want

「快递单」:填写目标收件人信息(如:要启动的UIAbility/ExtensionAbility、系统功能)

「快递包裹」:携带需要传递的附加数据(如:用户ID、订单信息、配置参数)

2.2、核心作用

在不同组件(UIAbility/ExtensionAbility)、不同应用(自家应用/系统应用/第三方应用)之间,实现“组件启动指令”和“数据信息”的传递

三、Want的类型

类型分为:显示Want和隐式Want

对比维度

显式 Want

隐式 Want

核心定义

Want 参数中明确指定 bundleName + abilityName

Want 参数中不指定 abilityName,通过 action/uri 等声明能力

目标对象

明确(知道具体要启动的组件)

不明确(仅知道需要的功能,由系统匹配组件)

核心字段

必须包含:bundleName、abilityName;可选:deviceId、parameters

核心字段:action(必选)、uri/type(可选);可省略:bundleName、entities

适用场景

1. 应用内组件启动(如首页 UIAbility 启动备份 ExtensionAbility);

2. API 12 前支持跨应用启动已知组件(API 12 后三方应用不推荐)

1. 调用系统功能(如打开相册、浏览器);

2. 跨应用调用未知组件(仅知道功能,不知道具体组件名);

3. 启动 ServiceExtensionAbility(需带 bundleName)

启动逻辑

直接定位目标组件,无需系统匹配

系统根据 action/uri 等条件匹配组件:

- 0 个匹配:启动失败;

- 1 个匹配:直接启动;

- 多个匹配(UIAbility):弹出用户选择框

关键限制

API 12 后,不推荐三方应用用显式 Want 拉起其他应用,推荐用应用链接

1. 带 abilityName 时,不允许隐式启动 ServiceExtensionAbility;

2. 带 bundleName 时,可通过 startServiceExtensionAbility () 隐式启动(返回优先级最高 / 第一个匹配组件);

3. entities 字段可省略(官方不推荐过度依赖)

代码示例核心特征

指定具体 bundleName 和 abilityName:

bundleName: 'com.samples.wantoverview'

abilityName: 'ExplicitAbility'

声明 action/uri,不指定 abilityName:

action: 'ohos.want.action.search'

uri: 'https://www.test.com/query'

优点

精准、高效,无匹配歧义,启动成功率高

灵活、解耦,无需依赖目标组件具体信息,适配多应用

缺点

耦合度高(目标组件名变更会导致启动失败);跨应用使用受限(API 12+)

匹配存在不确定性(可能无匹配 / 多匹配);需依赖系统组件声明的能力

四、显示Want与隐式Want匹配规则

类型

类型

匹配规则

核心优势

显式 Want

明确指定目标组件的「包名(bundleName)」和「组件名(abilityName)」

无需 “匹配”,直接根据指定信息定位组件

精准、高效,不会启动错误组件,适合应用内组件通信

隐式 Want

不指定具体组件,只声明要执行的「动作(action)」、「数据类型」等

系统会根据声明的条件,匹配所有符合要求的组件(自家应用 / 系统 / 第三方),用户可选择目标组件

灵活、解耦,无需知道目标组件的具体信息,适合调用系统功能 / 跨应用无明确组件信息的场景

五、Want使用场景

场景1:应用内启动组件(显示Want)

适用场景:从EntryAbility(Index)启动其他 UIAbility(如 “SecondAbility” 页面 Ability);

具体实现步骤:

步骤1:先明确项目结构

以「从主组件EntryAbility(首页)启动目标组件SecondAbility(二级页面组件)」为例,项目核心结构如下

说明:

  • EntryAbility:DevEco Studio 创建 Stage 项目时默认生成,作为应用主入口。
  • SecondAbility:手动创建(和EntryAbility同级),是本次要通过显式 Want 启动的目标组件。
  • module.json5:所有 Ability 组件必须在此文件中声明,否则无法被识别和启动(核心配置)。

步骤2:配置module.json5(声明目标组件SecondAbility

这里如果不配置,即使写了 Want 代码也无法启动目标组件

打开src/main/module.json5,在abilities数组中添加SecondAbility的声明(和EntryAbility并列):

步骤 3:实现目标组件SecondAbility(手动创建完整文件)

1、创建SecondAbility.ets(组件入口文件)

路径:src/main/ets/SecondAbility/SecondAbility.ets

import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
import { AbilityConstant, Want } from '@kit.AbilityKit';

export default class SecondAbility extends UIAbility {
  // 组件创建时触发
  onCreate(want:Want, launchParam:AbilityConstant.LaunchParam) {
    // 可选:接收从EntryAbility传递过来的Want参数
    console.log("SecondAbility 接收的Want参数:", JSON.stringify(want));
  }

  // 窗口创建时触发,加载二级页面UI
  onWindowStageCreate(windowStage: window.WindowStage) {
    super.onWindowStageCreate(windowStage);
    // 加载SecondIndex.ets页面(和EntryAbility逻辑一致)
    windowStage.loadContent('pages/SecondIndex', (err, data) => {
      if (err) {
        console.error("SecondAbility 加载页面失败:", err);
      } else {
        console.log("SecondAbility 加载页面成功");
      }
    });
  }
}

2. 创建SecondIndex.ets(二级页面 UI)

路径:src/main/ets/pages/SecondIndex.ets

// 简单的二级页面,仅做展示
@Entry
@Component
struct SecondIndex {
  build() {
    Column() {
      Text("这是通过显式Want启动的SecondAbility页面")
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 100 })
      Text("启动成功!")
        .fontSize(16)
        .margin({ top: 20 })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Start)
    .alignItems(HorizontalAlign.Center)
  }
}

备注:该页面需在main_pages.json5文件注册,因为loadContent加载的页面需是@Entry包裹的根页面,在main_pages.json5文件注册后才能正常跳转到该页面,否则跳转过来是空白的

步骤4:实现主组件EntryAbility页面(触发显式 Want 启动)

修改EntryAbility的首页Index.ets,添加按钮触发启动逻辑

路径:src/main/ets/pages/Index.ets

import { launchSecondAbility } from '../utils/wantUtils';

@Entry
@Component
struct Index {

  build() {
    Column() {
      Text("首页(EntryAbility)")
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 100 })

      // 启动按钮:点击触发显式Want启动SecondAbility
      Button("点击启动SecondAbility")
        .fontSize(18)
        .margin({ top: 50 })
        .width(280)
        .height(60)
        .onClick(() => {
          launchSecondAbility()
        })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Start)
    .alignItems(HorizontalAlign.Center)
  }
}

构建显式Want,启动SecondAbility

import { common, Want } from '@kit.AbilityKit'

// 核心方法:构建显式Want,启动SecondAbility
export async function launchSecondAbility() {
  try {
    // 1. 构建显式Want对象(必须指定bundleName和abilityName)
    const targetWant: Want = {
      deviceId: "",
      bundleName: "com.example.buildertest",
      abilityName: "SecondAbility",
      parameters: {
        userId: "123",
        pageTitle: "二级页面"
      }
    }
    // 2. 调用上下文的startAbility方法,启动目标组件
    const context = getContext() as common.UIAbilityContext
    await context.startAbility(targetWant)
    console.log("lucy== 显式Want 启动SecondAbility 成功");
  } catch (err) {
    console.error("lucy== 显式Want 启动SecondAbility 失败:", err);
  }
}

/*
 * 🌟🌟参数说明:🌟🌟
 * deviceId:为空表示本设备(应用内启动无需填写)
 * bundleName:应用包名(可在app.json5中查看,必须和项目一致)
 * abilityName:目标组件名(必须和module.json5中声明的SecondAbility一致)
 * parameters:参数可选:传递自定义参数(业务数据)
 * */

六、总结

1、核心定义:鸿蒙 Stage 模型中组件 / 应用间通信的信息载体,兼具 “组件启动指令” 和 “数据传递” 功能

2、两种核心类型:

显式 Want:指定bundleName+abilityName,精准启动应用内组件;

隐式 Want:不指定abilityName,通过action/uri匹配功能,用于调用系统 / 跨应用能力

3、核心作用:

启动目标组件(UIAbility/ExtensionAbility)+ 传递附加数据(如参数、uri)

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐