适合谁看

  • 想写好鸿蒙 insight_intent.json 的开发者

  • 想让应用被鸿蒙小艺搜索理解的人

  • 已经接了 Intents Kit,但配置还很松散的人

问题背景

很多入口配置的问题不是"格式错误",而是"语义太弱":

  • 名称不稳定(今天叫 openPage,明天改 navigateTo

  • 参数太随意(直接传路由字符串)

  • 候选值不清晰(不知道支持哪些页面)

  • 关键词和展示描述没有产品语义

鸿蒙系统入口如果写成这样,后面基本很难维护。小艺搜索也看不懂你在说什么。

项目中的真实场景

食界探味当前的入口配置在:

  • app/ohos/entry/src/main/resources/base/profile/insight_intent.json

完整配置:

{
  "insightIntents": [
    {
      "intentName": "JumpFunctionPage",
      "domain": "ToolsDomain",
      "intentVersion": "1.0.1",
      "srcEntry": "./ets/entryability/InsightIntentExecutorImpl.ets",
      "uiAbility": {
        "ability": "EntryAbility",
        "executeMode": ["foreground"]
      },
      "inputParams": [
        {
          "properties": {
            "pageId": {
              "type": "string",
              "enum": [
                {
                  "value": "search",
                  "displayName": "搜索美食",
                  "keywords": ["搜索", "找菜", "查菜"],
                  "displayDescription": "搜索全球美食与食材",
                  "icon": "https://abc.xx"
                },
                {
                  "value": "wish_box",
                  "displayName": "心愿单",
                  "keywords": ["心愿", "想吃"],
                  "displayDescription": "查看我的美食心愿",
                  "icon": "https://abc.xx"
                },
                {
                  "value": "ingredients",
                  "displayName": "食材探索",
                  "keywords": ["食材", "原料"],
                  "displayDescription": "浏览全球食材",
                  "icon": "https://abc.xx"
                },
                {
                  "value": "explore",
                  "displayName": "探索美食",
                  "keywords": ["探索", "推荐", "发现"],
                  "displayDescription": "浏览今日推荐与全球美食",
                  "icon": "https://abc.xx"
                },
                {
                  "value": "dish_detail",
                  "displayName": "查看菜品详情",
                  "keywords": ["菜品", "详情", "做法"],
                  "displayDescription": "打开指定菜品的详情页",
                  "icon": "https://abc.xx"
                }
              ]
            }
          }
        }
      ]
    }
  ]
}

核心实现

一、先定义稳定的 intent 名称

当前使用的是 JumpFunctionPage

这个名字本身就表达了用途:跳到功能页。它比模糊的 openPagenavigate 更稳定。

命名原则:

原则

好的例子

差的例子

表达意图

JumpFunctionPage

openPage

不包含实现细节

SearchDish

navigateToSearchScreen

稳定不变

JumpFunctionPage

goToPage(太泛)

语义清晰

ViewDishDetail

showContent

intent 名称一旦上线就很难改,因为鸿蒙系统会缓存这个名称。所以第一次就要想清楚。

二、参数要用结构化字段,不要直接写路由

当前输入参数的核心是 pageId,而不是 /search/wish-box 这类路由路径。

为什么用 pageId 而不是路由路径:

方式

示例

问题

路由路径

/search/wish-box

和 Flutter 实现耦合,改路由要改配置

结构化参数

pageId: "search"

和实现解耦,改路由不用改配置

pageId 是业务语义,不是实现细节。鸿蒙配置层只认识 search,不认识 /search。这样配置层和 Flutter 实现层保持解耦。

三、enum 要限制可选值

当前配置里对 pageId 做了枚举:

"enum": [
  { "value": "search", "displayName": "搜索美食" },
  { "value": "wish_box", "displayName": "心愿单" },
  { "value": "ingredients", "displayName": "食材探索" },
  { "value": "explore", "displayName": "探索美食" },
  { "value": "dish_detail", "displayName": "查看菜品详情" }
]

这一步很重要,因为它告诉鸿蒙系统"我真正支持哪些语义入口"。

enum 的作用:

作用

说明

限制参数范围

只接受这 5 个值,其他值会被拒绝

系统理解入口

小艺搜索知道你支持哪些功能

文档化

每个值都有 displayName,一目了然

校验

执行器可以用 VALID_PAGE_IDS.includes(pageId) 校验

四、展示名、关键词、描述不能随便填

每个 enum 值都有 3 个展示字段:

{
  "value": "search",
  "displayName": "搜索美食",
  "keywords": ["搜索", "找菜", "查菜"],
  "displayDescription": "搜索全球美食与食材"
}

这 3 个字段决定了小艺搜索怎么理解你的入口:

字段

作用

影响

displayName

用户在搜索结果中看到的名称

决定用户是否点击

keywords

小艺搜索匹配的关键词

决定用户搜索时能否找到

displayDescription

搜索结果中的描述文字

帮助用户理解入口功能

关键词设计原则:

原则

说明

示例

覆盖用户可能搜索的词

用户不会搜"pageId=search"

"搜索"、"找菜"、"查菜"

不要太泛

"美食"太泛,匹配所有入口

"搜索美食"比"美食"好

不要太窄

"牛肉咖喱搜索"太窄

"搜索"比"牛肉咖喱搜索"好

3-5 个关键词

太少匹配不到,太多匹配太杂

["搜索", "找菜", "查菜"]

小艺搜索的工作原理:

用户对小艺说:"帮我搜索美食"
  ↓
小艺在 insight_intent.json 中匹配关键词
  ↓
找到 "search" 入口的 keywords: ["搜索", "找菜", "查菜"]
  ↓
匹配成功 → 展示 "搜索美食" 入口
  ↓
用户点击 → 调起应用,传入 pageId="search"

如果 keywords 写得不好,小艺搜索就找不到你的入口。

五、配置层和执行层要对齐

配置层(insight_intent.json)定义了 5 个 pageId:

search, wish_box, ingredients, explore, dish_detail

执行层(InsightIntentExecutorImpl.ets)的白名单:

const VALID_PAGE_IDS: string[] = [
  'search', 'wish_box', 'ingredients', 'explore', 'dish_detail'
];

两边必须一致! 如果配置层加了一个新 pageId,执行层也要跟着加。否则系统会传入一个执行器不认识的值。

六、dish_detail 的特殊处理

dish_detail 是唯一需要额外参数的入口:

{
  "value": "dish_detail",
  "displayName": "查看菜品详情",
  "keywords": ["菜品", "详情", "做法"],
  "displayDescription": "打开指定菜品的详情页"
}

执行器会对它做特殊校验:

if (pageId === 'dish_detail' && (!dishId || dishId.length === 0)) {
  resolve(makeResult(-1, 'dishId type error'));
  return;
}

这说明:不是所有入口都一样简单。有些入口需要额外参数,配置层要体现这一点。

关键代码位置

文件

作用

app/ohos/entry/src/main/resources/base/profile/insight_intent.json

鸿蒙入口配置(本文核心)

app/ohos/entry/src/main/ets/entryability/InsightIntentExecutorImpl.ets

参数校验

配置层设计原则总结

原则

说明

食界探味的做法

稳定命名

intent 名称一旦上线就很难改

JumpFunctionPage

结构化参数

用 pageId 而不是路由路径

pageId: "search"

枚举限制

明确支持哪些入口

5 个 enum 值

语义化展示

displayName + keywords + 每个值都有

配置执行对齐

配置层和执行层的参数一致

两边都是 5 个 pageId

常见坑

  • 直接把 Flutter 路由字符串写进 insight_intent.json — 应该用 pageId,路由留给 Flutter

  • keywords 和 displayDescription 太空泛 — 应该覆盖用户可能搜索的词

  • enum 不限制,参数范围过大 — 应该用 enum 明确可选值

  • 配置层和执行层各自定义一套不同参数语义 — 两边必须一致

  • intent 名称太泛openPage 不如 JumpFunctionPage 表达清晰

  • 没有给每个 enum 值加 displayName — 小艺搜索无法展示友好的入口名称

  • 关键词覆盖不全 — 用户搜索"查菜"时找不到入口

可复用模板

insight_intent.json 模板

{
  "insightIntents": [
    {
      "intentName": "JumpFunctionPage",
      "domain": "YourDomain",
      "intentVersion": "1.0.0",
      "srcEntry": "./ets/entryability/IntentExecutorImpl.ets",
      "uiAbility": {
        "ability": "EntryAbility",
        "executeMode": ["foreground"]
      },
      "inputParams": [
        {
          "properties": {
            "pageId": {
              "type": "string",
              "enum": [
                {
                  "value": "home",
                  "displayName": "首页",
                  "keywords": ["首页", "主页", "推荐"],
                  "displayDescription": "浏览推荐内容"
                },
                {
                  "value": "profile",
                  "displayName": "我的",
                  "keywords": ["个人", "设置", "账户"],
                  "displayDescription": "查看个人信息"
                }
              ]
            }
          }
        }
      ]
    }
  ]
}

关键词设计模板

每个 enum 值的 keywords 应该:
  ✅ 覆盖用户可能搜索的词(3-5 个)
  ✅ 不要太泛("美食"太泛)
  ✅ 不要太窄("牛肉咖喱搜索"太窄)
  ✅ 包含同义词("搜索"、"找菜"、"查菜")
  ❌ 只有 1 个关键词(匹配率低)
  ❌ 只有技术术语(用户不会搜 "pageId")

配置执行对齐检查清单

每新增一个 pageId,检查:
  □ insight_intent.json 的 enum 里加了?
  □ displayName 起好了?
  □ keywords 覆盖了用户可能搜索的词?
  □ displayDescription 描述清楚了?
  □ InsightIntentExecutorImpl.ets 的 VALID_PAGE_IDS 加了?
  □ intent_navigation_channel.dart 的 _pageIdToRoute 加了?

本篇总结

鸿蒙 insight_intent.json 写得好不好,决定小艺搜索能不能真正理解你的应用入口。核心要点:

  1. 稳定命名JumpFunctionPage,不包含实现细节

  2. 结构化参数 — 用 pageId,不用路由路径

  3. 枚举限制 — 明确 5 个可选值,不接受任意参数

  4. 语义化展示 — 每个值都有 displayName + keywords + displayDescription

  5. 配置执行对齐 — 配置层和执行层的参数必须一致

把它当成系统语义配置,而不是普通 JSON 文件,质量会高很多。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐