前言
在 HarmonyOS 的 Stage 模型中,module.json5是每个 HAP 模块的核心配置文件,它决定了应用的入口、能力开放范围、设备兼容性和扩展能力注册方式。与传统的AndroidManifest.xml或 iOS 的Info.plist不同,HarmonyOS 的配置体系采用了双层结构(AppScope 级 + Module 级),使得多模块工程的管理更加灵活。本文以 小事记(xiaoshiji_ohos_app) 的module.json5为基础,深入解析每个配置字段的含义、skills隐式匹配机制和extensionAbilities的注册流程。
本文参考 HarmonyOS 官方文档:application-configuration-file-stage.md 和 application-models.md。
一、双层配置体系概览
1.1 AppScope 层与 Module 层的职责划分
HarmonyOS 工程采用双层配置结构:
| 层级 | 配置文件 | 路径 | 作用域 | 配置内容 |
|---|---|---|---|---|
| App 层 | app.json5 | AppScope/app.json5 | 整个应用 | bundleName、versionCode、vendor、应用图标 |
| Module 层 | module.json5 | entry/src/main/module.json5 | 单个 HAP 模块 | abilities、extensionAbilities、deviceTypes、pages |
小事记的app.json5配置如下:
{ "app": { "bundleName": "com.xiaoshiji.app", // 应用包名,全局唯一 "vendor": "xiaoshiji", // 供应商名称 "versionCode": 1000000, // 版本号(整数) "versionName": "1.0.0", // 版本名称(字符串) "icon": "$media:layered_image", // 应用图标资源引用 "label": "$string:app_name" // 应用名称资源引用 } }关键字段说明:
bundleName— 应用的唯一标识符,遵循反向域名规则,一旦发布不可更改versionCode— 用于版本比较的整数,每次更新必须递增versionName— 展示给用户的版本名称,遵循语义化版本规范$media:layered_image— 资源引用语法,$media前缀指向resources/base/media/目录下的资源文件
1.2 资源引用语法
HarmonyOS 使用$前缀引用资源文件,支持多种资源类型:
| 引用语法 | 资源类型 | 对应目录 | 示例 |
|---|---|---|---|
$string:xxx | 字符串资源 | resources/base/element/string.json | $string:app_name |
$color:xxx | 颜色资源 | resources/base/element/color.json | $color:start_window_background |
$media:xxx | 媒体资源 | resources/base/media/ | $media:startIcon |
$profile:xxx | 配置资源 | resources/base/profile/ | $profile:main_pages |
$float:xxx | 浮点数资源 | resources/base/element/float.json | $float:corner_radius |
提示:使用资源引用而非硬编码值的最大好处是多语言和多设备适配——系统会根据设备语言和屏幕密度自动选择对应限定符下的资源文件。
二、module 根字段详解
2.1 基础标识字段
{ "module": { "name": "entry", // 模块名称,工程内唯一 "type": "entry", // 模块类型:entry / feature / har / hsp "description": "$string:module_desc", "mainElement": "EntryAbility", // 模块的主入口 Ability "deviceTypes": ["phone"], // 支持的设备类型 "deliveryWithInstall": true, // 是否随安装包一起交付 "installationFree": false, // 是否支持免安装 "pages": "$profile:main_pages" // 页面路由配置 } }type字段的四种取值:
| 类型 | 说明 | 使用场景 | 是否可独立运行 |
|---|---|---|---|
entry | 应用主入口模块 | 应用的主 HAP | ✅ |
feature | 功能特性模块 | 按需加载的功能模块 | ✅ |
har | 静态共享包 | 代码和资源静态打包,多模块引用 | ❌ |
hsp | 动态共享包 | 运行时共享,多个 entry/feature 共用 | ❌ |
deviceTypes可选值:
phone— 手机tablet— 平板car— 车机tv— 智慧屏wearable— 穿戴设备2in1— 二合一设备
2.2 页面配置$profile:main_pages
pages字段引用了resources/base/profile/main_pages.json文件,其中定义了模块的所有页面路由:
// resources/base/profile/main_pages.json { "src": [ "pages/Index", "pages/HomePage", "pages/RecordPage", "pages/EventDetailPage", "pages/StatisticsPage", "pages/SearchPage", "pages/TimelineViewPage", "pages/CalendarViewPage", "pages/CalendarImportPage", "pages/SettingsPage", "pages/DataBackupPage", "pages/TagManagementPage", "pages/WitnessListPage", "pages/RelatedPeoplePage", "pages/AutoGeneratePage", "pages/MemoryVideoPage" ] }每个页面路径对应ets/pages/目录下的一个.ets文件。页面路径的注册遵循以下规则:
- 路径以
pages/开头,不含文件扩展名 - 路径必须与
ets/pages/下的文件一一对应 @Entry装饰的组件通过import router引用时,url参数与这些路径一致
// Index.ets — 使用 pages 中的注册路径跳转 import router from '@ohos.router'; @Entry @Component struct Index { aboutToAppear(): void { router.replaceUrl({ url: 'pages/HomePage' }); // 与 main_pages.json 中的注册路径一致 } }三、abilities 配置深度解析
3.1 EntryAbility 的完整配置
{ "abilities": [ { "name": "EntryAbility", // Ability 名称,模块内唯一 "srcEntry": "./ets/entryability/EntryAbility.ets", // 入口文件路径 "description": "$string:EntryAbility_desc", // 描述 "icon": "$media:layered_image", // 图标 "label": "$string:EntryAbility_label", // 标签 "startWindowIcon": "$media:startIcon", // 启动窗口图标 "startWindowBackground": "$color:start_window_background", // 启动窗口背景色 "exported": true, // 是否允许外部应用启动 "skills": [...] // 隐式匹配规则 } ] }3.2 启动窗口的视觉优化
startWindowIcon和startWindowBackground共同决定了用户点击应用图标后到看到首页之前的视觉过渡:
startWindowIcon— 启动时显示的图标,通常使用应用图标startWindowBackground— 启动窗口的背景色,建议与应用首页背景色一致
// 正确的颜色资源引用 // resources/base/element/color.json { "color": [ { "name": "start_window_background", "value": "#F8F9FA" // 与 HomePage 的背景色一致,消除视觉跳跃 } ] }提示:启动窗口的显示时间由系统控制,无法通过代码缩短。优化体验的关键是让启动窗口背景色与首页背景色一致,避免出现白屏闪烁。
3.3 exported 字段的权限控制
exported字段决定了其他应用是否能够启动当前 Ability:
| exported 值 | 含义 | 使用场景 |
|---|---|---|
true | 允许外部应用唤醒 | 主入口 Ability,需要被桌面启动 |
false | 仅本应用内可调用 | 备份 Ability、内部页面 |
// 外部应用尝试启动本应用的 EntryAbility let want = { bundleName: "com.xiaoshiji.app", abilityName: "EntryAbility" }; // 如果 exported: false,该调用会失败,返回错误码 this.context.startAbility(want, (err) => { if (err.code) { console.error("无法启动目标 Ability"); } });四、skills 隐式匹配机制
4.1 匹配规则
skills数组定义了 Ability 能够响应的隐式 Want匹配规则。当系统或其他应用发送一个隐式 Want 时,会根据skills中的配置进行匹配:
{ "skills": [ { "entities": ["entity.system.home"], // 实体类别 "actions": ["ohos.want.action.home"] // 操作类型 } ] }匹配规则:
- Want 的
action必须与 skills 中至少一个actions匹配 - Want 的
entities必须包含 skills 中所有entities(skills 中定义的 entities 是“必须包含“的关系) - 如果 skills 未定义
entities,则匹配时不检查 entities
4.2 桌面图标的启动匹配
当用户在桌面点击应用图标时,系统发送的隐式 Want 为:
{ action: "ohos.want.action.home", entities: ["entity.system.home"] }这个 Want 匹配到EntryAbility的 skills 配置,从而启动应用。如果skills配置错误,桌面图标将无法启动应用。
4.3 多种匹配模式的配置
一个 Ability 可以配置多个skills数组元素,每个元素代表一组匹配规则:
{ "skills": [ { // 规则一:桌面图标启动 "entities": ["entity.system.home"], "actions": ["ohos.want.action.home"] }, { // 规则二:处理分享 "entities": ["entity.system.share"], "actions": [ "ohos.want.action.sendData", "ohos.want.action.sendMultipleData" ], "uris": [ { "scheme": "https", "host": "*.xiaoshiji.com", "path": "/share/*" } ] } ] }uris匹配规则:
| 字段 | 说明 | 示例 |
|---|---|---|
scheme | URI 协议 | https、file、content |
host | 主机名 | *.xiaoshiji.com(支持通配符) |
port | 端口号 | 8080 |
path | 精确路径 | /share/event |
pathStartWith | 路径前缀 | /share/ |
pathPattern | 路径正则 | /share/[0-9]+ |
type | MIME 类型 | text/plain、image/* |
4.4 隐式匹配与显式启动的对比
| 对比维度 | 隐式启动 | 显式启动 |
|---|---|---|
| 指定方式 | action+entities+uri | bundleName+abilityName |
| 匹配过程 | 系统遍历所有应用的 skills | 直接定位目标 Ability |
| 灵活性 | 高,解耦调用方和被调用方 | 低,需要知道目标的具体信息 |
| 安全性 | 低,任何匹配的应用都可以响应 | 高,精确指定目标 |
| 性能 | 稍慢,需要系统匹配 | 快,直接启动 |
五、extensionAbilities 配置
5.1 备份扩展 Ability 的注册
小事记中注册了一个BackupExtensionAbility,用于数据备份和恢复:
{ "extensionAbilities": [ { "name": "EntryBackupAbility", "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", "type": "backup", // 扩展类型 "exported": false, // 不对外暴露 "metadata": [ { "name": "ohos.extension.backup", // 系统约定的元数据名称 "resource": "$profile:backup_config" // 备份配置文件 } ] } ] }5.2 ExtensionAbility 的类型体系
type值 | 说明 | 基类 |
|---|---|---|
backup | 数据备份恢复 | BackupExtensionAbility |
service | 后台服务 | ServiceExtensionAbility |
form | 卡片(Widget) | FormExtensionAbility |
workScheduler | 延迟任务调度 | WorkSchedulerExtensionAbility |
inputMethod | 输入法 | InputMethodExtensionAbility |
accessibility | 无障碍服务 | AccessibilityExtensionAbility |
fileShare | 文件共享 | FileShareExtensionAbility |
window | 窗口扩展 | WindowExtensionAbility |
5.3 metadata 配置
metadata数组用于向系统传递扩展的配置信息,每个 metadata 包含name和resource两个字段:
{ "metadata": [ { "name": "ohos.extension.backup", "resource": "$profile:backup_config" // 引用 profile 目录下的配置文件 } ] }backup_config.json文件定义了备份的具体规则:
// resources/base/profile/backup_config.json { "allowToBackup": true, "includes": [ "data/storage/el2/database/", "data/storage/el2/base/preferences/" ], "excludes": [ "data/storage/el2/base/cache/" ] }六、多模块配置实战
6.1 多 Module 工程的配置结构
当应用扩展为多模块时,每个模块有独立的module.json5:
AppScope/app.json5 ← 应用级配置,全局唯一 entry/src/main/module.json5 ← 主模块 feature1/src/main/module.json5 ← 功能模块 1 feature2/src/main/module.json5 ← 功能模块 26.2 跨模块 Ability 的启动
// 在主模块中启动 feature 模块的 Ability let want = { bundleName: "com.xiaoshiji.app", moduleName: "feature_share", // 指定模块名称 abilityName: "ShareAbility" }; this.context.startAbility(want);6.3 使用 createModuleContext 访问其他模块的资源
import { application } from '@kit.AbilityKit'; // 获取 feature 模块的 Context application.createModuleContext(this.context, 'feature_share') .then((moduleContext) => { // 读取该模块的字符串资源 let desc = moduleContext.resourceManager.getStringSync( $r('app.string.feature_desc').id ); console.log(`模块描述: ${desc}`); });七、配置文件的常见错误排查
7.1 页面路径注册错误
// ❌ 错误:页面路径遗漏或拼写错误 { "pages": "$profile:main_pages" } // main_pages.json 中缺少 pages/HomePage 的注册 // 运行时 router.pushUrl({ url: 'pages/HomePage' }) 会返回错误码 200007 // ✅ 正确:确保所有页面都在 main_pages.json 中注册 { "src": [ "pages/Index", "pages/HomePage", // ... ] }7.2 skills 配置错误导致桌面图标无法启动
// ❌ 错误:缺少 actions 或 entities 配置 { "skills": [ { // 缺少 "ohos.want.action.home" "entities": ["entity.system.home"] } ] } // ✅ 正确 { "skills": [ { "entities": ["entity.system.home"], "actions": ["ohos.want.action.home"] } ] }7.3 资源引用路径错误
// ❌ 错误:资源文件不存在 "startWindowBackground": "$color:nonexistent_color" // ✅ 正确:确保资源文件在 element/color.json 中定义 { "color": [ { "name": "start_window_background", "value": "#F8F9FA" } ] }八、配置文件的版本演进
8.1 API 版本与配置项变化
| API 版本 | 配置变化 | 说明 |
|---|---|---|
| API 9 | 引入module.json5 | 替代 FA 模型的config.json |
| API 10 | 新增installationFree | 支持免安装应用 |
| API 11 | 新增deliveryWithInstall | 支持按需交付 |
| API 12 | Kit 化导入路径 | @kit.AbilityKit替代@ohos.ability.xxx |
| API 14 | 新增multiApp配置 | 支持多应用共享进程 |
九、配置文件自动生成工具
9.1 使用 DevEco Studio 的配置可视化
DevEco Studio 提供了module.json5的图形化编辑界面,可以通过Open Editor按钮在可视化视图中编辑配置:
- 在项目管理器中双击
module.json5 - 点击编辑器右上角的
Open Editor - 在可视化界面中填写配置项
- 保存后自动生成
module.json5文件
9.2 使用 hvigor 的自定义配置
在build-profile.json5中,可以通过buildOption配置编译时的 module.json5 覆盖:
{ "app": { "products": [ { "name": "default", "targetSdkVersion": "6.0.2(22)", "compatibleSdkVersion": "6.0.2(22)", "runtimeOS": "HarmonyOS", "buildOption": { "strictMode": { "caseSensitiveCheck": true, "useNormalizedOHMUrl": true } } } ] } }总结
本文从xiaoshiji_ohos_app项目的module.json5出发,深入解析了 HarmonyOS Stage 模型的双层配置体系。核心要点如下:
- 双层配置:
app.json5负责应用级信息,module.json5负责模块级配置,两者配合使用 - Ability 声明:通过
abilities数组注册 UIAbility,每个 Ability 可独立配置启动窗口、图标和导出权限 - skills 隐式匹配:通过
actions+entities+uris的组合规则,实现灵活的组件间通信 - extensionAbilities:通过备份、服务、卡片等多种扩展类型,为应用增添后台能力
- 资源引用:使用
$string/$color/$media/$profile等前缀引用资源文件,实现多设备适配
下一篇文章将深入解析备份扩展 Ability 的注册机制与 onBackup/onRestore 生命周期,详细讲解BackupExtensionAbility的完整实现流程。
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
相关资源:
- 小事记项目源码:xiaoshiji_ohos_app
- 官方文档 - 配置文件:application-configuration-file-stage.md
- 官方文档 - 应用模型:application-models.md
- 官方文档 - 包结构:application-package-structure-stage.md
- 官方文档 - 配置文件概述:application-configuration-file-overview-stage.md
- 官方文档 - 启动选项:application-startup-options.md
- 官方文档 - 应用包开发:application-package-dev.md
- 开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net