HarmonyOS app.json5 到底管什么:先把应用级配置从 module.json5 拆出来【鸿蒙心迹】

你是不是也在想——“鸿蒙这么火,我能不能学会?”
答案是:当然可以!
这个专栏专为零基础小白设计,不需要编程基础,也不需要懂原理、背术语。我们会用最通俗易懂的语言、最贴近生活的案例,手把手带你从安装开发工具开始,一步步学会开发自己的鸿蒙应用。
不管你是学生、上班族、打算转行,还是单纯对技术感兴趣,只要你愿意花一点时间,就能在这里搞懂鸿蒙开发,并做出属于自己的App!
📌 关注本专栏《零基础学鸿蒙开发》,一起变强!
每一节内容我都会持续更新,配图+代码+解释全都有,欢迎点个关注,不走丢,我是小白酷爱学习,我们一起上路 🚀
全文目录:
前言
刚接触 HarmonyOS 工程时,app.json5 和 module.json5 很容易被混在一起理解:两个都是 JSON5,里面都可能看到 icon、label,一个工程里又可能有多个 Module。等到修改包名、升级版本或者处理桌面图标时,问题就来了——这项配置到底应该改在哪一层?
这篇不铺开整个工程配置体系,只解决一个具体问题:先把应用级配置和模块级配置拆清楚,再用一个最小工程理解 bundleName、versionCode、versionName、icon、label、vendor 分别负责什么。
截至 2026 年 9 月,HarmonyOS 7 对应 API 26,HarmonyOS 开发套件从 API 26.0.0 开始采用 X.Y.Z 的语义化 API 版本格式。这里要先区分两个概念:API 26 是开发套件/API 的版本,而本文这些 app.json5 字段属于应用配置,并不是需要 import 某个 Kit 后才能调用的运行时 API。
一、先确定 app.json5 的位置:它站在整个应用这一层
Stage 模型工程中,可以先把目录简化成这样理解:
MyApplication/
├── AppScope/
│ ├── app.json5
│ └── resources/
│ └── base/
│ ├── element/
│ │ └── string.json
│ └── media/
│ └── ...
├── entry/
│ └── src/main/
│ ├── module.json5
│ ├── ets/
│ └── resources/
├── build-profile.json5
└── oh-package.json5
华为官方当前的 HarmonyOS 文档把“应用配置文件”明确拆成 app.json5 和 module.json5 两部分;官方实践工程中也把 AppScope/app.json5 标为应用级配置,而 entry/src/main/module.json5 用来承载模块配置。
所以理解这两个文件时,可以先记住一个边界:
AppScope/app.json5 描述的是“这个 App 是谁”;module.json5 描述的是“这个 Module 里面有什么、怎么运行”。
这比死记字段更重要。
二、一个最小 app.json5 先看全貌
这次用一个最小应用作为例子,不引入网络、数据库或者 ArkUI 业务代码,只处理应用身份、版本和展示资源。
可以把 AppScope/app.json5 组织成下面这样:
{
"app": {
"bundleName": "com.example.appconfigdemo",
"vendor": "example",
"versionCode": 1000000,
"versionName": "1.0.0",
"icon": "$media:app_icon",
"label": "$string:app_name"
}
}
真正需要关注的是六个字段:
| 字段 | 解决的问题 | 更接近哪类信息 |
|---|---|---|
bundleName | 这个应用是谁 | 应用身份 |
versionCode | 系统如何识别应用版本变化 | 版本管理 |
versionName | 应用版本如何命名 | 版本展示 |
icon | 应用使用哪个图标资源 | 应用展示 |
label | 应用使用哪个名称资源 | 应用展示 |
vendor | 应用开发厂商描述 | 应用元信息 |
打包后的应用信息中同样能够解析出 bundleName、vendor、versionName、versionCode、icon、label 等 App 信息,这也能帮助我们理解:这些不是某个页面自己的属性,而是应用包层面的元数据。
1. bundleName:应用身份不要当成普通字符串
bundleName 是最需要谨慎修改的一项。
官方文档把 Bundle 名称作为应用唯一性标识;当前华为开放能力的接入文档也明确要求,AppScope/app.json5 中的 bundleName 要与 AppGallery Connect 创建应用时的包名保持一致。
例如:
"bundleName": "com.example.appconfigdemo"
因此它和页面路由名称、Module 名称不是一回事。尤其应用已经进入签名、联调或发布阶段后,不应该把修改 bundleName 当成普通重命名。
华为官方的签名问题说明给出了一个很典型的现象:如果项目中的包名已经修改,而签名配置仍然绑定旧包名,构建或安装时可能出现 BundleName in the project configuration does not match that in the SigningConfigs。官方给出的处理方向是重新处理对应的签名配置。
所以遇到“刚改完包名就签名失败”时,不要先去怀疑 ArkTS 代码,应该先检查应用身份与签名是否仍然一致。
2. versionCode 和 versionName:两个版本号不是一回事
这两个字段经常一起改,但职责并不相同。
"versionCode": 1000000,
"versionName": "1.0.0"
versionName 是版本名称,适合表达类似 1.0.0、2.3.1 这样的版本语义;versionCode 则是系统侧用于识别应用版本的版本代码。
这里比较容易出现一个理解偏差:不能因为 versionName 从 1.0.0 改成 1.1.0,就认为系统侧的版本管理自然完成了。
官方资料在涉及版本更新、证书切换等场景时,会明确要求修改 app.json5 中的 versionCode。
实际项目里比较稳妥的做法,是把两者作为一组版本信息维护:
"versionCode": 1000001,
"versionName": "1.0.1"
一个负责机器识别,一个负责版本名称表达,不要只盯着其中一个。
3. icon 和 label:引用的是资源,不是把内容直接写进配置
应用名称和图标通常不要直接硬编码成最终内容,而是通过资源引用:
"icon": "$media:app_icon",
"label": "$string:app_name"
例如应用名称可以放在:
AppScope/resources/base/element/string.json
对应资源:
{
"string": [
{
"name": "app_name",
"value": "AppConfig Demo"
}
]
}
图标资源则放在 AppScope/resources 对应的媒体资源目录中。华为官方近期实践工程同样采用 AppScope/resources/base/element/string.json 存放应用名称,并在 AppScope/resources/base/media/ 下管理应用图标。
资源引用还有一个直接的工程价值:不同设备或资源限定条件下,可以提供不同资源。官方 FAQ 就记录了一个实际问题——如果只在手机限定目录配置图标,而平板对应目录以及 base 中都没有可用资源,平板上可能读取不到预期图标。
4. vendor:它不是 bundleName 的替代品
"vendor": "example"
vendor 用于描述应用开发厂商信息。官方配置资料把它与 bundleName 分开定义,打包后的 AppInfo 中也分别保留 bundleName 和 vendor。
所以不要把 vendor 理解成另一种包名,也不要拿它承担应用唯一标识的职责。
真正承担应用身份识别职责的是 bundleName。
三、为什么还会在 module.json5 里看到 icon 和 label?
看到这里,一个很自然的问题是:既然 app.json5 已经有 icon、label,为什么 module.json5 的 Ability 配置里也可能出现它们?
这正是应用级和组件级配置最容易混淆的地方。
例如一个 Module 可以包含类似这样的 Ability 配置:
{
"module": {
"name": "entry",
"type": "entry",
"mainElement": "EntryAbility",
"deviceTypes": [
"phone",
"tablet"
],
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"icon": "$media:layered_image",
"label": "$string:EntryAbility_label",
"exported": true
}
]
}
}
这里的重点不是复制完整模板,而是观察层级:
app.json5
└── app
├── bundleName
├── versionCode
├── versionName
├── icon
└── label
module.json5
└── module
├── name
├── type
├── deviceTypes
├── abilities
├── extensionAbilities
└── requestPermissions
官方对 module.json5 的说明中,模块基本信息、Ability/ExtensionAbility 组件信息以及应用运行所需权限都属于这一层;官方多设备工程文档也通过修改 module.json5 的 type 和 deviceTypes 来决定 Module 类型及其支持的设备。
所以可以这样判断:
要描述整个应用的身份、版本和默认展示信息,先找 app.json5;要描述某个模块里的 Ability、ExtensionAbility、权限、设备类型等,找 module.json5。
而 icon、label 之所以两边都可能看到,是因为应用层和具体组件层都存在展示信息。官方针对手机、平板图标不一致问题的排查建议,也明确要求同时检查 app.json5 与 module.json5 中相关的 icon、label 配置。
四、app.json5、module.json5 和 build-profile.json5 再分一次
如果只区分前两个文件,实际开发中还不够,因为 SDK 版本、签名和 Product 配置经常又被误塞到 app.json5。
可以用三个问题来判断:
“这个应用是谁?”
看:
AppScope/app.json5
例如 bundleName、版本、应用图标和名称。
“这个模块能做什么?”
看:
entry/src/main/module.json5
例如 Module 类型、支持设备、Ability、ExtensionAbility、权限声明等。
“这个工程怎么构建?”
看:
build-profile.json5
例如 Product、签名配置以及 SDK 相关构建配置。官方最新 Hvigor 构建示例中,compatibleSdkVersion 等构建参数就在工程级 build-profile.json5 中,而不是 app.json5。
这也解释了为什么本文虽然以 HarmonyOS 7 为背景,却没有在 app.json5 示例里硬塞一个所谓“API 26 字段”。
HarmonyOS 7 对应 API 26.0.0 是开发版本关系;bundleName、versionCode、label 这些则属于应用配置。两者有关联,但不是同一个配置维度。
五、几个容易理解错的地方
app.json5 不是“所有全局配置都往这里放”
“应用级”不等于“工程里所有东西的全局配置”。
签名、Product、SDK 构建参数有自己的 build-profile.json5;Module 的 Ability、ExtensionAbility 和权限也有自己的 module.json5。
如果看到一个配置需求就往 app.json5 塞字段,很容易写出配置规范中根本不存在的属性。
改 bundleName 后,要把签名关系一起检查
这是一个非常适合形成固定排查习惯的地方。
官方已经明确记录了包名变化后与 SigningConfigs 不匹配的构建问题。
因此修改 bundleName 后,建议马上确认:
app.json5 bundleName
↓
AppGallery Connect 应用包名
↓
工程签名配置
三者不要只改其中一个。
图标异常时,不要只盯着 app.json5
特别是多设备工程。
如果手机正常、平板异常,除了确认 icon 引用,还要检查 AppScope/resources 和 Module 资源目录下是否存在设备限定资源,以及 module.json5 中 Ability 是否也配置了相关图标。官方已经给出了这类跨设备图标异常的排查案例。
权限不是写在 app.json5
例如某个 Kit 要求声明权限,应该按照对应能力文档把权限配置到 Module 的 requestPermissions 中。
官方当前文档对 module.json5 的职责说明就包含“应用运行过程中所需的权限信息”。
所以看到:
ohos.permission.XXXX
第一反应应该是检查具体能力文档和 module.json5,而不是给 app.json5 增加一个自创的 permissions 字段。
六、实际项目可以按这个顺序排查
遇到应用名称、图标、版本或包名相关问题时,可以按一条固定链路检查:
- 先确认问题属于应用级还是 Module/Ability 级;
- 应用身份问题检查
AppScope/app.json5的bundleName; - 版本问题同时检查
versionCode和versionName; - 名称、图标问题检查
label、icon的资源引用以及AppScope/resources; - 多设备展示异常继续检查资源限定目录和
module.json5中的组件配置; - 修改
bundleName后继续核对 AppGallery Connect 与签名配置; - 如果问题实际是 SDK、Product 或签名构建参数,再转到
build-profile.json5,不要继续修改app.json5。
这条顺序的意义在于先判断“配置属于哪一层”,再判断具体字段。否则一个桌面图标问题,很容易一路排查到 ArkUI 页面代码里,而真正的问题仍然留在应用包配置。
开发经验总结
app.json5 本身并不复杂,真正容易出错的是配置边界。
可以把这篇文章压缩成四句话:
bundleName 定义应用身份,修改它要同步关注 AppGallery Connect 和签名。
versionCode 与 versionName 都属于版本信息,但承担的角色不同,发布版本时不要只改展示名称。
icon、label 是资源引用,多设备出现差异时要把 AppScope、资源限定目录以及 Module/Ability 配置一起检查。
应用身份和版本放在 app.json5 思考;Ability、ExtensionAbility、权限、设备类型放在 module.json5 思考;SDK、Product、签名等构建问题再去看 build-profile.json5。
把这三层先拆开,后面再接触多 HAP、HAR、HSP 或更复杂的工程结构时,配置文件会清楚很多。
如果你的工程里已经有多个 Module,可以顺手检查一次:现在那些“看起来像全局配置”的内容,究竟是在描述整个应用,还是只应该属于某个 Module?
❤️ 如果本文帮到了你…
- 请点个赞,让我知道你还在坚持阅读技术长文!
- 请收藏本文,因为你以后一定还会用上!
- 如果你在学习过程中遇到bug,请留言,我帮你踩坑!
更多推荐

所有评论(0)