在这里插入图片描述

你是不是也在想——“鸿蒙这么火,我能不能学会?”
答案是:当然可以!
这个专栏专为零基础小白设计,不需要编程基础,也不需要懂原理、背术语。我们会用最通俗易懂的语言、最贴近生活的案例,手把手带你从安装开发工具开始,一步步学会开发自己的鸿蒙应用。
不管你是学生、上班族、打算转行,还是单纯对技术感兴趣,只要你愿意花一点时间,就能在这里搞懂鸿蒙开发,并做出属于自己的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 字段。

六、实际项目可以按这个顺序排查

遇到应用名称、图标、版本或包名相关问题时,可以按一条固定链路检查:

  1. 先确认问题属于应用级还是 Module/Ability 级;
  2. 应用身份问题检查 AppScope/app.json5 的 bundleName;
  3. 版本问题同时检查 versionCode 和 versionName;
  4. 名称、图标问题检查 label、icon 的资源引用以及 AppScope/resources;
  5. 多设备展示异常继续检查资源限定目录和 module.json5 中的组件配置;
  6. 修改 bundleName 后继续核对 AppGallery Connect 与签名配置;
  7. 如果问题实际是 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,请留言,我帮你踩坑!
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐