首发于华为开发者论坛:https://developer.huawei.com/consumer/cn/blog/topic/03224137955596434

先说结论:app.icon 和 abilities[].icon 这两个字段,网上(包括我自己先前记的笔记)常说有唯一正确组合。不成立。 我在自己 22 个工程上读了一遍,三种配法都在架。

我是怎么写下那条"铁律"的

两次驳回,先后隔了挺久。

一次是把 ability.icon 指向了分层图,被判图标为空;另一次反过来,把 app.icon 指向扁平 png,AGC 上架自检判"应用图标资源需分层"。这两次的具体措辞我手里只有当时记在项目文档里的转述,原件没归档,所以不逐字引,只说结论方向。

两条报错互相印证得太漂亮了:一个说这边不能分层,一个说那边必须分层。我当时的推理是——那唯一正确组合就是 app.icon = 分层、ability.icon = 扁平(startIcon)。写进文档,标了个红,还打算拿它去把其它工程"统一"一遍。

自检页那条要求是真的,可以随时复现

先把真的部分说清楚,免得矫枉过正。分层素材的规格要求在 AGC 上架自检页上随时能看到:

前景图 + 背景图各 1024×1024;不允许自行裁切圆角(背景须满铺到四角);不允许在资源内添加内间距。

配置文件就是 AppScope/resources/base/media/layered_image.json:

{"layered-image":{"background":"$media:background","foreground":"$media:foreground"}}

这一条我没有异议。有异议的是"只有一种组合能过"。

反例:一个用完全相反配法、正常在架的应用

2026-08-01,我逐文件核了一遍(不是靠记忆推断),发现自己有个主 App 是这么配的:

  • app.icon → $media:app_icon,而且 AppScope/resources/base/media/ 下只有 app_icon.png 这一个文件,没有分层三件套,它就是张扁平 PNG
  • abilities[].icon → $media:layered_image

跟我写下的"铁律"完全相反,而它已经在架好几个版本了。

我差一点就按铁律去把它改掉。改了会怎样不好说,但那是个正在正常过审的配置,动它纯属拿在架状态去赌一个我并没验证过的规则。

顺手把 22 个工程全读了一遍,得到三种:

组合app.iconabilities[].icon数量
A$media:layered_image$media:startIcon9 个主 App
B$media:app_icon(扁平 PNG)$media:layered_image1 个主 App
C$media:app_icon(扁平 PNG)$media:startIcon7 个元服务

三种,不是两种。B 和 C 都直接推翻了"app.icon 必须分层"。

根因:我把"我踩到的报错"当成了"平台的规则"

那两条报错都是真的,但它们只证明那两次的那两种配法在当时没过。从"这两种没过"跳到"只有一种能过",中间那一步没有任何证据支撑,是我自己补上去的。

而且这一步的成本是不对称的:结论说宽了,最多多试一次;结论说死了(“只能这么配”),我会拿着它去改一个本来好好的工程,还会在将来每次遇到图标问题时,先想起这条错的铁律,而不是去查。

校验器的确切边界——版本差异、应用形态差异、还是跟素材本身有关——我到现在没查清。这句必须写出来,否则就是用一个新的绝对化结论替换旧的。

所以我现在这么配,也不再去动别人

新工程用 A 组,多个工程实证在架:

// AppScope/app.json5
"icon": "$media:layered_image"

// entry/src/main/module.json5 → abilities[]
"icon": "$media:startIcon"

分层素材放 AppScope/resources/base/media/:foreground.png + background.png + layered_image.json。工程里 entry 侧通常已经有这三个文件,直接复制过去就行,不用重画。

遇到已在架、配法跟你不一样的工程,别去"统一"它。

验证判据:解包读字段,不是"看着对"

图标这东西最容易犯的错就是拿眼睛验收。判据是收包后解包核字段:

unzip -p <出包>.hap module.json | \
  python3 -c "import json,sys; m=json.load(sys.stdin); print(m['app']['icon'], m['module']['abilities'][0]['icon'])"

两个字段同时符合本工程既定组合才算过。真被判"图标为空"时,先拿审核附件确认它说的是哪个字段,再动手。

最后交代清楚我不知道的部分

本文最有用的是那个反例,不是我的结论。你要是在自己账号下读到第四种配法,那说明边界比我知道的还宽,欢迎在评论里贴出来。

反过来也别读成"扁平随便用"——那两次自检和驳回是真实发生过的,我能确定的只有"唯一正解"这个说法不成立,至于边界在哪,未知。

另外两件顺手提醒的事:商店图标是第三个东西,别跟这俩混,AGC 应用信息页上传的是单张正方形直角图,平台自己加圆角蒙层,你别预裁;模块级 module.icon / module.label 是非法字段,加了 hvigor 直接报错。


这是《鸿蒙开发踩坑实录》第 1 篇。这类「我以为的唯一正解」后来还撞过几次。

本文由作者与 AI 协作整理,事实经作者核验。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐