【OpenHarmony/HarmonyOs 】HarmonyOS NEXT 工程配置详解:app.json5、module.json5 与 main_pages.json
【OpenHarmony/HarmonyOs 】HarmonyOS NEXT 工程配置详解:app.json5、module.json5 与 main_pages.json
🧱 HarmonyOS 项目能否安装、启动和跳转,不只取决于 ArkTS 代码。应用级配置、模块级配置和页面清单共同描述了包名、设备类型、权限、Ability 与路由入口。
一、三份配置各管什么
AppScope/app.json5
└─ 整个应用:包名、版本、图标、厂商
entry/src/main/module.json5
└─ entry 模块:Ability、权限、设备、扩展能力
entry/src/main/resources/base/profile/main_pages.json
└─ 当前模块可加载的 ArkUI 页面
应用可以包含多个模块,但包名和版本属于全局;页面与 Ability 则属于具体模块。先理解层级,再修改配置,能够避免字段放错位置。
系统从桌面图标进入 ArkUI 页面的完整链路可以概括为:
点击桌面图标
→ app.json5 确认应用身份、名称和图标
→ module.json5 根据 skills 找到 EntryAbility
→ srcEntry 加载 EntryAbility.ets
→ onWindowStageCreate() 调用 loadContent()
→ main_pages.json 验证目标页面已经注册
→ 构建 WelcomePage 或 HomePage
因此,“能安装但打开白屏”未必是 ArkUI 布局错误,也可能是 Ability 路径、页面清单、资源引用或 loadContent() 目标不一致。
二、应用级 app.json5
{
"app": {
"bundleName": "shan.lian.daohang",
"vendor": "shan.lian.daohang",
"versionCode": 1000000,
"versionName": "1.0.0",
"icon": "$media:layered_image",
"label": "$string:app_name"
}
}
bundleName
它是应用的稳定身份,必须与 AGC/AppGallery Connect 中登记的包名一致。发布后随意更换会被视为另一个应用,也会影响签名、数据目录和云服务配置。
versionCode 与 versionName
versionName 面向用户,例如 1.0.0;versionCode 用于系统判断升级顺序,发布新版本时必须递增。不要只改显示版本而忘记内部版本号。
资源引用
$media:layered_image、$string:app_name 引用资源,而不是硬编码路径。系统可根据设备、语言和主题选择合适资源。
常见资源引用包括:
$string:app_name 字符串
$color:start_window_background 颜色
$media:layered_image 图片或分层图标
$profile:main_pages Profile 配置
建议把版本概念也分清:versionName 面向用户,versionCode 判断升级顺序,而本地数据的 schemaVersion 应独立维护。应用升级不一定修改数据格式,数据迁移也不能只靠显示版本判断。
三、模块类型与入口
{
"module": {
"name": "entry",
"type": "entry",
"mainElement": "EntryAbility",
"pages": "$profile:main_pages"
}
}
type: "entry" 表示这是应用入口模块,mainElement 指向主要 Ability。pages 通过资源引用连接页面清单,而不是直接在此写所有页面。
模块还配置了:
"deliveryWithInstall": true,
"installationFree": false
前者表示模块随安装交付,后者描述当前模块不是免安装形态。应用能够拉起元服务,不代表应用自身就是元服务,这两个概念不能混淆。未来若将 AI、工具箱拆成 feature 模块,还要重新规划模块依赖和按需交付。
四、声明支持的设备
"deviceTypes": [
"phone",
"tablet",
"2in1"
]
声明支持并不代表 UI 已经完成适配。开发者仍要检查窗口断点、横竖屏、输入方式、信息密度和安全区。配置决定“允许运行”,布局决定“是否好用”。
| 设备 | 重点检查 |
|---|---|
| 手机 | 底部手势区、两列 Grid、单手操作 |
| 平板 | 三至四列布局、横屏、内容最大宽度 |
| 2in1 | 键鼠焦点、窗口缩放、悬停反馈 |
五、网络权限
"requestPermissions": [
{ "name": "ohos.permission.INTERNET" }
]
LinkOS 需要请求搜索建议和加载网页,因此必须声明网络权限。权限应遵循最小化原则:未使用的位置、相机、麦克风不要提前申请。涉及用户授权的权限还需要运行时请求和拒绝后的降级路径。
权限设计可以连续追问三个问题:是否真的需要、应在什么时机申请、用户拒绝后如何降级。例如模拟语音搜索不应提前申请麦克风;真实语音功能也应在用户点按麦克风时再申请,并在拒绝后保留文字搜索。
六、UIAbility 配置
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"icon": "$media:layered_image",
"label": "$string:EntryAbility_label",
"startWindowIcon": "$media:startIcon",
"startWindowBackground": "$color:start_window_background",
"exported": true,
"skills": [
{
"entities": ["entity.system.home"],
"actions": ["ohos.want.action.home"]
}
]
}
]
srcEntry 必须与源码路径一致;启动窗口图标和背景决定 ArkUI 首帧构建前的过渡画面;skills 声明它可以作为桌面入口启动。
exported 会影响组件是否可被其他应用访问。能设为 false 的组件不要公开,公开组件要验证传入 Want,避免把外部参数当可信数据。
启动窗口会在 ArkUI 首帧完成前显示。为了减少视觉闪烁,startWindowBackground 应接近首屏背景,启动图标尺寸应稳定。Preferences 初始化属于首屏决策所需操作,可以在 Ability 中等待;天气、推荐和 AGC 非关键请求则应延后异步执行。
skills 不只是桌面声明。未来若增加 Deep Link、分享接收或文件打开,也需要对应 action/entity,并在 Ability 中校验 Want 参数的类型、长度和协议。外部入口越多,攻击面越大。
七、页面清单
{
"src": [
"pages/v2/WelcomePage",
"pages/v2/HomePage",
"pages/v2/MiniAppPage",
"pages/v2/AIAssistantPage",
"pages/v2/MinePage",
"pages/v2/WebViewPage"
]
}
新增 .ets 页面后还要加入清单。常见问题包括路径大小写不一致、移动文件后未更新清单、路由使用旧目录、把不带 @Entry 的普通组件误当页面。
项目仍保留 v1 源码,但当前清单只登记 v2 生产页面。这可以避免旧页面继续进入正式路由。路由字符串还可以集中管理:
export class AppRoutes {
static readonly WELCOME = 'pages/v2/WelcomePage';
static readonly HOME = 'pages/v2/HomePage';
static readonly WEB = 'pages/v2/WebViewPage';
}
常量减少业务代码中的拼写错误,但最终仍要与 main_pages.json 同步。
八、扩展能力
项目注册了备份扩展:
"extensionAbilities": [
{
"name": "EntryBackupAbility",
"srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets",
"type": "backup",
"exported": false,
"metadata": [
{
"name": "ohos.extension.backup",
"resource": "$profile:backup_config"
}
]
}
]
扩展能力由系统在特定场景调度,不等同于普通 UI 页面。exported: false 也符合内部系统能力的最小暴露原则。
当前备份 Ability 只记录回调日志,因此配置代表“已注册能力骨架”,不是“收藏已经完成备份”。真正落地还需要定义数据范围、快照版本、恢复校验和失败回滚。
九、构建配置之间的一致性
还要检查 build-profile.json5 中 targetSdkVersion、compatibleSdkVersion、产品和签名配置。SDK 版本、使用的 API 和设备系统不匹配时,可能出现编译成功但安装失败,或使用了目标版本不可用接口。
项目还启用了严格检查:
"strictMode": {
"caseSensitiveCheck": true,
"useNormalizedOHMUrl": true
}
大小写检查可以提前暴露路径问题,规范化 OHM URL 有助于统一模块导入。遇到错误时应修正真实路径,不应为了短期通过构建而关闭严格模式。
十、AGC、签名与环境一致性
接入 AGC 时,控制台应用、bundleName、签名材料与 agconnect-services.json 必须属于同一个项目。常见错误包括下载了另一个应用的配置、debug/release 签名不匹配、修改包名后没有重新配置云服务,以及把示例文件当成真实配置。
需要特别强调:agconnect-services.json 是客户端识别 AGC 项目的配置,不是保存第三方私密密钥的地方。DeepSeek 等服务密钥仍应只存在于云函数环境变量。
建议区分构建环境:
Debug:开发签名、测试服务地址、详细诊断日志
Release:正式签名、正式地址、受控日志、混淆
任何环境都不能把真实业务密钥硬编码进源码。
十一、四类常见故障
1. router 提示页面不存在
检查页面是否登记、路径是否误加 .ets、大小写是否一致,以及页面移动后是否仍使用旧路由。
2. 安装后无法从桌面启动
检查 mainElement、Ability 的 name/srcEntry、home skill 和签名,不要只检查页面 build 方法。
3. 网络接口全部失败
依次检查 INTERNET 权限、HTTPS 地址、设备网络、证书和服务域名。声明权限并不能解决证书或接口错误。
4. 模拟器正常,真机无法安装
重点检查签名、Profile、设备系统版本、SDK 兼容范围和 bundleName。
十二、排错顺序 ✅
- 确认 JSON5 语法和尾逗号;
- 检查资源名是否真实存在;
- 检查 Ability 名称与
srcEntry; - 检查页面是否登记;
- 检查 bundleName 与 AGC 配置;
- 检查 SDK、签名与设备版本;
- 清理构建缓存后重新同步;
- 查看 hilog 中的明确错误码。
十三、发布前检查表
- bundleName 与 AGC 控制台完全一致;
- versionCode 已递增,versionName 展示正确;
- 图标、应用名和启动背景使用正式资源;
- 删除未使用权限;
- 所有生产页面已登记,v1 页面未暴露;
- Ability 的 exported 符合最小权限;
- SDK 与目标真机匹配;
- release 签名和 Profile 正确;
- AGC 文件属于正式项目且没有业务密钥;
- release 包完成冷启动、路由、网络和备份回调验证。
十四、总结
app.json5 定义应用身份,module.json5 描述模块能力,main_pages.json 注册页面入口,构建配置再决定 SDK 与签名。把这几层关系理顺,权限、路由、Ability、备份和多设备支持才会形成完整工程,而不是一组互不理解的配置文件。✅

更多推荐

所有评论(0)