HarmonyOS abilities 配置拆解:name、srcEntry、label、icon、exported 到底和 ArkTS 类怎么对应【鸿蒙心迹】

大家好,我是[晚风依旧似温柔],新人一枚,欢迎大家关注~
本文目录:
前言
刚接触 HarmonyOS Stage 模型时,module.json5 里的这段配置很容易让人产生一个错觉:name 是不是 ArkTS 类名?srcEntry 和页面路由有什么区别?exported 和 export default class 又是不是一回事?
abilities
├ name
├ srcEntry
├ label
├ icon
└ exported
其实把这几个字段放到一条链路里理解,事情会清楚很多:
abilities 负责向系统注册 UIAbility,srcEntry 把这条注册信息连接到 ArkTS 实现文件,而 ArkTS 文件中的 UIAbility 子类才负责生命周期和窗口逻辑。
本文就围绕这条对应关系,搭一个最小的双 UIAbility 示例,把几个最容易混淆的字段拆开。
一、先搞清楚:abilities 不是 ArkTS 类定义
Stage 模型工程中,一个模块可以在 module.json5 的 abilities 数组里声明 UIAbility。华为官方文档中的多个当前示例,都采用下面这种结构:
{
"module": {
"name": "entry",
"type": "entry",
"mainElement": "EntryAbility",
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"icon": "$media:layered_image",
"label": "$string:EntryAbility_label",
"exported": true
}
]
}
}
官方近期文档给出的多 UIAbility 配置同样是在 abilities 中分别填写 name、srcEntry、icon、label 等信息。
这里最重要的认识是:
module.json5 描述“系统里存在什么组件”,ArkTS 文件描述“这个组件运行起来以后做什么”。
所以不能把 abilities 当成 ArkTS 类的另一种写法。它属于应用组件注册信息。
可以先记住下面这张对应表:
| 配置 | 主要作用 | 和 ArkTS 文件的关系 |
|---|---|---|
name | UIAbility 的逻辑名称 | 用于标识、定位目标 Ability |
srcEntry | UIAbility 对应代码入口路径 | 指向 .ets 实现文件 |
label | UIAbility 对用户显示的名称资源 | 不决定 ArkTS 类名 |
icon | UIAbility 的图标资源 | 不决定代码入口 |
exported | 控制组件对其他应用的可调用性 | 和 ArkTS 的 export 不是一回事 |
官方资料对 Ability 信息的定义中,也把 name 作为 Ability 名称,把 label 描述为 Ability 对用户显示的名称,把 icon 描述为 Ability 的图标资源。
二、name:它首先是 Ability 的逻辑名称
先看:
"name": "EntryAbility"
这里比较容易理解错。
name 的核心身份是 Ability 的逻辑名称,而不是“ArkTS 类声明语法”。
这个名称会进入组件标识体系。例如使用 Want 显式指定目标 UIAbility 时,会通过 abilityName 指定目标 Ability。华为当前 Want 文档明确说明:abilityName 表示待启动的 Ability 名称,并且需要在一个应用范围内保证唯一。
例如:
let want: Want = {
bundleName: 'com.example.abilityconfigdemo',
abilityName: 'SettingsAbility'
};
这里的:
abilityName: 'SettingsAbility'
对应的首先是 module.json5 中注册的:
{
"name": "SettingsAbility"
}
而不是让运行时去扫描工程,寻找一个恰好叫 SettingsAbility 的 TypeScript/ArkTS 类。
实际工程中,把配置名称、文件名和类名保持一致仍然是非常好的工程习惯:
name
↓
SettingsAbility
srcEntry
↓
./ets/settingsability/SettingsAbility.ets
ArkTS
↓
export default class SettingsAbility extends UIAbility
这样阅读配置时可以直接定位实现代码,也不容易在多 UIAbility 工程中产生混乱。
三、srcEntry:真正把配置和代码连起来的字段
如果说 name 回答的是“这个组件叫什么”,那么:
"srcEntry": "./ets/settingsability/SettingsAbility.ets"
回答的就是:
这个组件对应的代码在哪里。
华为官方当前开发资料在介绍 ExtensionAbility 注册时,对 srcEntry 的解释非常直接:它表示当前 ExtensionAbility 组件所对应的代码路径;当前其他官方配置示例也沿用同样的“配置组件 + srcEntry 指向实现文件”的组织方式。
UIAbility 工程同样可以看到这种结构:
entry
└─ src
└─ main
├─ ets
│ ├─ entryability
│ │ └─ EntryAbility.ets
│ └─ settingsability
│ └─ SettingsAbility.ets
└─ module.json5
对应配置:
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets"
},
{
"name": "SettingsAbility",
"srcEntry": "./ets/settingsability/SettingsAbility.ets"
}
]
这也是为什么新增一个 .ets 文件,并不等于自动新增了一个系统可识别的 UIAbility。
代码文件存在是一件事,在 abilities 中完成组件注册是另一件事。
官方关于多 UIAbility 的实际配置示例,也是先创建对应 UIAbility 实现,再把新的 Ability 添加到模块的 abilities 中。
四、ArkTS 类到底对应在哪里
以入口 UIAbility 为例,当前官方代码普遍使用 Ability Kit:
import { UIAbility } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
export default class EntryAbility extends UIAbility {
onWindowStageCreate(windowStage: window.WindowStage): void {
windowStage.loadContent('pages/Index', (err) => {
if (err.code) {
console.error(`loadContent failed: ${JSON.stringify(err)}`);
return;
}
console.info('loadContent success');
});
}
}
UIAbility 属于 Ability Kit 的 Stage 模型能力。当前官方 API 体系仍将 @ohos.app.ability.UIAbility 列为“带界面的应用组件”,官方示例使用 @kit.AbilityKit 导入 UIAbility。UIAbility 相关 Stage 模型基础接口从 API version 9 起进入当前接口体系。
这里真正需要分清三层:
module.json5
│
│ name = EntryAbility
│ srcEntry = ./ets/entryability/EntryAbility.ets
▼
EntryAbility.ets
│
│ export default class EntryAbility extends UIAbility
▼
onCreate / onWindowStageCreate / onForeground ...
module.json5 不是页面路由表。
EntryAbility.ets 也不是 ArkUI 页面本身。
UIAbility 创建 WindowStage 后,可以再通过:
windowStage.loadContent('pages/Index')
加载具体 ArkUI 页面。
因此还可以再补上一层:
abilities
↓
UIAbility
↓
WindowStage
↓
pages/Index
↓
ArkUI 页面
把这几层分开以后,很多目录结构问题就容易定位了。
五、label 和 icon:它们描述的是组件展示信息
再看:
"label": "$string:EntryAbility_label",
"icon": "$media:layered_image"
它们和 srcEntry 完全不是一个维度。
label 对应 Ability 向用户展示的名称信息,icon 对应 Ability 图标资源。官方 AbilityInfo 资料也分别将二者定义为 Ability 对用户显示的名称和 Ability 图标资源。
因此常见配置会使用资源引用:
"label": "$string:EntryAbility_label",
"icon": "$media:layered_image"
而不是把代码文件写到这里。
例如字符串资源可以放在模块的资源目录中:
{
"string": [
{
"name": "EntryAbility_label",
"value": "Ability 配置示例"
},
{
"name": "SettingsAbility_label",
"value": "设置"
}
]
}
icon 则引用对应 media 资源。
这里还有一个很实用的排查点:如果配置引用了不存在的 $media 资源,构建阶段会报资源引用错误。华为 DevEco Studio 官方 FAQ 给出的例子就是 icon 引用了不存在的 media 资源后导致编译失败。
所以:
srcEntry 找不到
和:
icon 资源找不到
虽然都写在同一个 Ability 配置对象中,本质却是两类完全不同的问题。
六、exported:千万不要和 export default 混在一起
这是这几个字段里最值得单独拆出来的一个。
配置文件中有:
"exported": false
ArkTS 文件中又有:
export default class SettingsAbility extends UIAbility {
}
两个地方都有 export,但它们根本不是一个概念。
ArkTS:
export default
属于语言模块的导出语义。
而 module.json5:
"exported": true
属于 应用组件暴露配置,决定该 Ability 是否允许被其他应用调用。
华为官方 2026 年的 DevEco Studio FAQ 给出了一个很直观的案例:Stage 模型运行时如果出现 ability visible false deny request,官方给出的检查方法就是将对应 abilities 中的 exported 设置为 true。
所以不能写成这样的推理:
ArkTS 写了 export default
↓
其他应用就能启动这个 Ability
这是错误的概念关联。
正确理解应该是:
export default
↓
ArkTS 模块层面的默认导出
exported
↓
HarmonyOS 应用组件层面的对外暴露配置
两者所在层级完全不同。
对于只打算在应用内部使用的业务 UIAbility,不应该因为看到 ArkTS 中存在 export default,就顺手把 module.json5 的 exported 也理解成同一个开关。
七、搭一个最小的双 UIAbility 示例
现在把关系组合起来。
目标很简单:
EntryAbility
↓
首页
SettingsAbility
↓
设置页面
module.json5 可以组织成:
{
"module": {
"name": "entry",
"type": "entry",
"mainElement": "EntryAbility",
"pages": "$profile:main_pages",
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"label": "$string:EntryAbility_label",
"icon": "$media:layered_image",
"exported": true,
"startWindowIcon": "$media:startIcon",
"startWindowBackground": "$color:start_window_background",
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"ohos.want.action.home"
]
}
]
},
{
"name": "SettingsAbility",
"srcEntry": "./ets/settingsability/SettingsAbility.ets",
"label": "$string:SettingsAbility_label",
"icon": "$media:layered_image",
"exported": false,
"startWindowIcon": "$media:startIcon",
"startWindowBackground": "$color:start_window_background"
}
]
}
}
当前华为官方多 UIAbility 示例同样采用在 abilities 中分别注册两个组件,并为每个组件指定独立 name 与 srcEntry 的方式。
然后建立:
ets/
├─ entryability/
│ └─ EntryAbility.ets
├─ settingsability/
│ └─ SettingsAbility.ets
└─ pages/
├─ Index.ets
└─ Settings.ets
SettingsAbility.ets:
import { UIAbility } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
export default class SettingsAbility extends UIAbility {
onWindowStageCreate(windowStage: window.WindowStage): void {
windowStage.loadContent('pages/Settings', (err) => {
if (err.code) {
console.error(`loadContent failed: ${JSON.stringify(err)}`);
return;
}
console.info('Settings page loaded');
});
}
}
这个例子真正需要看的并不是页面长什么样,而是下面的链路:
"name": "SettingsAbility"
│
├── 系统侧组件名称
│
"srcEntry": "./ets/settingsability/SettingsAbility.ets"
│
├── 找到实现文件
│
export default class SettingsAbility extends UIAbility
│
├── UIAbility 实现
│
onWindowStageCreate(...)
│
└── loadContent('pages/Settings')
↓
ArkUI 页面
这就是 abilities 和 ArkTS 文件之间最核心的对应关系。
八、几个特别容易理解错的地方
1. name 不是文件路径
下面两个字段不要互换职责:
"name": "SettingsAbility",
"srcEntry": "./ets/settingsability/SettingsAbility.ets"
前者是组件名称,后者才是代码入口路径。
Want 显式指定目标 Ability 时关注的是 abilityName。
2. srcEntry 不是 ArkUI 页面地址
"srcEntry": "./ets/entryability/EntryAbility.ets"
和:
windowStage.loadContent('pages/Index')
不是同一件事。
前者把 UIAbility 注册信息连接到实现代码;后者是在 WindowStage 中加载页面内容。
3. label 不等于 name
name 是 Ability 名称。
label 是面向用户的展示名称。
所以这两项完全可以承担不同职责:
"name": "SettingsAbility",
"label": "$string:SettingsAbility_label"
不要为了显示中文名称去修改 Ability 的逻辑名称。
4. icon 不是 startWindowIcon
本文重点是:
"icon": "$media:layered_image"
工程里经常还能看到:
"startWindowIcon": "$media:startIcon"
二者不要混为一个字段。DevEco Studio 官方 FAQ 明确把 startWindowIcon 和 startWindowBackground 放在启动界面配置中说明。
5. exported 也不是权限声明
exported 处理的是组件对外暴露问题,它本身不是:
requestPermissions
也不是某个:
ohos.permission.XXX
本文这个最小示例没有为了 name、srcEntry、label、icon 或 exported 额外申请运行时权限。涉及具体跨应用启动能力时,还应继续按照目标组件和调用接口的官方约束检查权限、启动规则以及组件可见性,不能把 exported: true 理解成“绕过权限检查”。
九、版本和 API Level 应该怎么理解
这个主题还有一个容易出现的版本误区:不要给每个 module.json5 字段机械套一个 ArkTS API Level。
name、srcEntry、label、icon、exported 在这里首先属于 Stage 模型的模块配置,而不是五个需要 import 后调用的 ArkTS API。
与本文代码直接相关的运行时部分是 Ability Kit 的 Stage 模型 UIAbility 体系。当前华为官方 API 文档仍提供 @ohos.app.ability.UIAbility、UIAbilityContext 等能力;UIAbilityContext 文档明确说明其首批接口从 API version 9 开始支持,并且仅可在 Stage 模型下使用。当前推荐代码示例使用 @kit.AbilityKit 导入相关能力。
因此迁移本文思路时,更稳妥的检查方式是:
先确认工程是不是 Stage 模型
↓
检查当前 SDK 下 module.json5 schema
↓
确认 UIAbility / Ability Kit API 版本
↓
再检查具体调用接口的设备和权限限制
而不是看到 exported 就试图寻找一个所谓的 exported() ArkTS API。
十、实际项目中怎么排查
遇到“新增 UIAbility 后启动不到”“配置改了但表现不对”之类问题,可以按下面顺序检查:
- 先看
abilities是否真的注册了目标 UIAbility。 只有.ets文件不够。 - 检查
name。 如果通过 Want 启动,重点核对abilityName与注册的 Ability 名称。 - 检查
srcEntry。 路径、目录和文件名是否与实际工程一致。 - 检查 ArkTS 实现。 对应文件是否按照 UIAbility 组件方式组织,并正确继承
UIAbility。 - 再检查页面加载。 UIAbility 已经找到,不代表
loadContent()指向的 ArkUI 页面就一定正确。 - 检查资源引用。
label、icon、startWindowIcon等引用的$string、$media资源是否真实存在。 - 最后看对外启动条件。 如果调用涉及其他应用,继续检查
exported、组件启动规则以及具体接口要求。
官方构建 FAQ 也说明,module.json5 字段缺失或拼写错误可能直接触发 Schema validate failed;报错中的 instancePath、missingProperty、propertyNames 可以用来定位具体 Ability 配置。
开发经验总结
这几个配置项真正值得记住的,不是每个字段的中文翻译,而是它们所在的层次:
abilities
↓
注册系统组件
name
↓
组件逻辑名称
srcEntry
↓
组件实现代码入口
export default class ... extends UIAbility
↓
ArkTS 中的 UIAbility 实现
loadContent(...)
↓
加载 ArkUI 页面
label、icon 补充的是组件展示信息,exported 处理的是组件对其他应用的暴露边界。
尤其要把两组概念彻底分开:
name ≠ label
srcEntry ≠ ArkUI 页面路由
exported ≠ export default
icon ≠ startWindowIcon
理解到这里,再去看一个包含多个 UIAbility 的 module.json5,就不会只看到一大堆配置字段了,而是能直接读出:系统注册了哪些组件、每个组件的代码入口在哪里、哪个组件对外暴露,以及它最终会加载哪一个页面。
如果正在整理一个多 UIAbility 工程,可以专门检查一次:现在工程里每一个 abilities[].name,是否都能沿着 srcEntry → UIAbility 实现 → loadContent 页面 这条链路准确定位。这个检查对于发现“配置层”和“页面层”混在一起的问题很有价值。
如果觉得有帮助,别忘了点个赞+关注支持一下~
喜欢记得关注,别让好内容被埋没~
更多推荐



所有评论(0)