都 2025 了,还不会一键发版?——「鸿蒙应用打包、签名与发布」这点事儿,今天一次讲透好不好!

🏆本文收录于「滚雪球学SpringBoot」专栏(全网一个名),手把手带你零基础入门Spring Boot,从入门到就业,助你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
环境说明:Windows 10 + IntelliJ IDEA 2021.3.2 + Jdk 1.8
前言
打工人心声:写功能很快乐,发版像过独木桥。打包、签名、上架、各种校验与合规,一路红线等着你踩。别慌,这篇用工程视角 + 实操脚本 + 清单化检查,把鸿蒙(HarmonyOS / OpenHarmony)应用的打包、签名与发布从“玄学”掰成“流程”。读完你能把“能跑”稳定地变成“能上架”。还得有点人话与幽默——不然谁看呀🙂
你将收获什么
- HAP 与 APP 包结构:它俩是什么关系、目录里都装了些啥
- 签名机制:证书、Profile、调试/发布签名、离线/CI 签名姿势
- 发布流程与规范:版本、权限、隐私、包体、截图与合规自查
- 脚本化落地:Hvigor/CLI 打包、签名与产物校验的小样例
- Checklist:能拯救你凌晨 Re-Upload 的“最后 10 分钟”
一、先把名词扣稳:HAP 与 APP 到底啥关系?
1)一句话版
- HAP(Harmony Ability Package):模块级安装包。一个 HAP 对应一个模块(如
entry、feature_x)。 - APP(App Pack):应用级打包产物,把一个或多个 HAP(含按架构/按特性拆分的 HAP)再装进一个壳,用于分发与安装。
2)结构示意(精简)
HAP 内部(模块包):
myapp-entry-default.hap
├─ module.json5 # 模块清单(名称、入口、权限、设备类型、能力)
├─ resources/ # 资源(多语言/分辨率/深浅色)
├─ ets/ # ArkTS/ETS 编译产物(或 js/so 等)
├─ libs/
│ ├─ arm64-v8a/*.so
│ └─ riscv64/*.so
├─ assets/ # 运行时资源(不参与编译,随包分发)
├─ pack.info # 打包信息(构建元数据)
└─ signature/ # 签名块(发布签名或调试签名)
APP 内部(应用包):
myapp-1.4.2-release.app
├─ HAP/
│ ├─ myapp-entry-default.hap
│ └─ myapp-feature-share.hap
├─ app.json5 # 应用层清单(bundleName、版本、icon 等)
├─ pack.info
└─ signature/ # 应用层签名(与证书/配置文件绑定)
形象点讲:HAP 是积木块,APP 是装满积木块的盒子。商店分发通常用 APP;独立分发某个特性/形态时,也可能投放单 HAP(视商店策略而定)。
二、构建:Hvigor/DevEco 一把梭,别手剥洋葱
下面示例把「可复制粘贴」放在第一位——你可以放进项目
scripts/里直接跑,CI 上也好改。
1)项目关键清单
app.json5(应用级):
bundleName:全局唯一(反域名);version:code(整数,自增)与name(人类可读)。
// app.json5(片段)
{
"app": {
"bundleName": "com.acme.supernotes",
"vendor": "Acme Inc.",
"version": { "code": 42, "name": "1.4.2" },
"icon": "$media:app_icon",
"label": "$string:app_name"
}
}
module.json5(模块级):
name、type(entry/feature/har等);deviceTypes(phone/tablet/car/wearable…);abilities(UIAbility等)、requestPermissions(用途要对齐隐私描述)。
// module.json5(片段)
{
"module": {
"name": "entry",
"type": "entry",
"deviceTypes": [ "phone", "tablet" ],
"abilities": [{
"name": "MainAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"label": "$string:app_name",
"icon": "$media:app_icon"
}],
"requestPermissions": [
{ "name": "ohos.permission.CAMERA", "reason": "$string:perm_camera" },
{ "name": "ohos.permission.LOCATION", "reason": "$string:perm_location" }
]
}
}
2)本地打包(Release)
- DevEco Studio:
Build > Build APP(s)选择Release; - Hvigor CLI(推荐拉到 CI):
# 1) 安装依赖(ohpm)
ohpm install
# 2) 产出 Release HAP(多模块会各自生成 HAP)
./hvigorw assembleRelease
# 3) 打 APP(把多个 HAP 合并为 APP)
./hvigorw app -p product=release
# 产物通常在 ./build/default/outputs/
小贴士:本地打包前,先
Clean Project,再Rebuild,避免老资源卡在缓存里“闹鬼”。
三、签名机制:证书 + Profile + 签名块,三角形缺一不可
1)你需要哪些东西?
- 应用证书(.p12 或等价格式):包含私钥,用于对包签名。
- Profile(调试/发布配置文件):绑定证书、公钥、包名、设备/分发范围等,告诉系统“这包能在什么环境跑”。
- 签名参数:别名(alias)、签名算法、证书链、时间戳等。
调试与发布用的 Profile 与证书通常分开。调试包能装在测试设备,上架必须用发布证书 + 发布 Profile。
2)在工程里配置签名(示例)
signingConfigs(hvigor 配置片段)
文件路径因模板不同而异,核心是给
release指定证书与 profile。
// hvigor/ohos/signingConfigs.js(示例)
module.exports = {
debug: {
storeFile: 'signing/debug/my_debug_cert.p12',
storePassword: process.env.DEBUG_STORE_PWD,
keyAlias: 'debug_key',
keyPassword: process.env.DEBUG_KEY_PWD,
profile: 'signing/debug/debug-profile.p7b'
},
release: {
storeFile: 'signing/release/my_release_cert.p12',
storePassword: process.env.RELEASE_STORE_PWD,
keyAlias: 'release_key',
keyPassword: process.env.RELEASE_KEY_PWD,
profile: 'signing/release/release-profile.p7b'
}
}
在 hvigorfile.js 里引用:
const signing = require('./ohos/signingConfigs');
ohosApp({
signingConfigs: signing,
// 其他构建参数……
});
环境变量(如
RELEASE_STORE_PWD)不要写死在仓库;CI 用“机密变量”注入即可。
3)CI 离线签名流程(常见做法)
- 构建未签名 HAP/APP(可通过构建参数输出 unsigned 包);
- 签名 Job 拉取证书与 profile(CI 安全库),调用签名工具对产物签名;
- 验签(校验签名块与证书链);
- 产物上传到制品库或商店。
优点:开发机无需接触发布证书;证书权限集中、可审计。
四、发布前的“九连问”(市场发布规范 · 实操视角)
商店规则可能不断更新,但底层逻辑万变不离其宗。把这些点做扎实,扣分概率立刻下降。
1)元数据与版本
bundleName:不可和他人重名;一旦上架,后续版本必须相同。- 版本号:
version.code单调递增;version.name对用户友好即可。 - 渠道标识:若有多渠道包,请勿用不同
bundleName伪装渠道(容易被拒)。
2)权限与隐私
- 只申请用得上的权限;弹窗按场景触发(不要开屏就要定位/相机)。
- 隐私政策:应用内可达(设置—隐私);对每项权限写明用途、采集范围、保留期、撤回方式。
- 第三方 SDK 列表:如用到统计/广告/分享,需在说明中列出并做最小化配置。
3)适配与包体
- 设备类型:
deviceTypes与实际设计一致;不支持就别勾(车机/可穿戴可分 HAP)。 - ABI:仅包含你支持的架构(比如
arm64-v8a);别把全集都塞进来。 - 包体限制:大二进制(模型、视频)尽量拆到 资源包/在线加载;图片/动画做 WebP/压缩。
4)内容与展示
- 图标/截图/描述:风格一致、清晰、勿含第三方商标(除非授权)。
- 评级/分级:如涉及用户生成内容(UGC),说明审核与举报机制。
- 无障碍:关键流程可达、字号与对比度合规,键盘/读屏可用(加分项)。
5)稳定性与性能
- 首启 ≤ 2s(主页面可交互):Skeleton + 懒加载。
- 崩溃率:灰度前先过“真机回归 + 设备矩阵”;日志脱敏。
- 功耗:后台场景停用长连接/定位/传感器,前后台策略对齐申报。
一句话:把“隐私、权限、内容、稳定”四条线拉直,提审就顺滑。
五、把流程脚本化:从“一次点错”变成“永不出错”
1)一键打包与签名(示例脚本)
#!/usr/bin/env bash
# scripts/build_release.sh
set -euo pipefail
export RELEASE_STORE_PWD="${RELEASE_STORE_PWD:?missing}"
export RELEASE_KEY_PWD="${RELEASE_KEY_PWD:?missing}"
echo "[1/4] Install deps"
ohpm install
echo "[2/4] Build HAPs (release)"
./hvigorw assembleRelease
echo "[3/4] Pack APP"
./hvigorw app -p product=release
OUT="./build/default/outputs/app/release"
APP=$(ls "$OUT"/*.app | head -n1)
echo "[4/4] Verify signature"
hap-tool verify --file "$APP" # 示意命令,按你使用的工具替换
echo "✅ Done: $APP"
2)产物体检(自查脚本)
#!/usr/bin/env node
// scripts/app_lint.js
const fs = require('fs');
const path = process.argv[2];
if (!path || !fs.existsSync(path)) {
console.error('Usage: node app_lint.js <path-to-app>');
process.exit(1);
}
// 伪检查:你可以解包后校验以下字段
const checklist = [
'bundleName present',
'version.code monotonic',
'module.json5 requestPermissions reason provided',
'contains only expected ABIs',
'assets size under threshold',
'signature block exists'
];
console.log('Running lint on', path);
for (const item of checklist) console.log(' •', item);
console.log('✅ Lint passed (demo)');
真正在 CI 里,你可以把 APP 解包成临时目录,读取
app.json5/module.json5做静态校验;同时跑一个 devices-smoke(真机自动冒烟)确保安装、启动、主要路径可用。
六、实操问与答(坑位警示标语)
Q1:同一个应用多个 HAP 怎么取舍?
A:按功能/形态拆。entry.hap 放主 UIAbility;独立功能(如分享、打印)做 feature.hap,按 deviceTypes 精准投放。别用 HAP 当“多渠道”。
Q2:签名密钥丢了?
A:这不是“如果”,是“何时”。立刻停更旧密钥对应的线上版本,申请新证书与 Profile,发布新包并迁移。务必在团队与 CI 做密钥托管与轮换计划。
Q3:调试包能上架吗?
A:不行。调试 Profile 只允许在指定设备安装。上架必须走发布证书 + 发布 Profile,并通过商店的静态/动态检查。
Q4:多设备(平板/车机)要做多个包吗?
A:看功能是否差异巨大。常见做法是同一应用下多 HAP,每个 HAP 设定不同 deviceTypes,资源与布局做自适配;极端差异再考虑分应用。
七、发布前最终 Checklist(打印贴墙!)
元信息
- [ ]
bundleName固定 & 唯一 - [ ]
version.code比上一个版本更大 - [ ]
icon/label系列资源齐全(暗/亮、密度、圆角)
签名
- [ ] 使用发布证书 + 发布 Profile
- [ ] CI/本地签名一致可复现
- [ ] 验签通过(证书链、时间戳、签名块)
权限与隐私
- [ ] 仅保留必要权限(
requestPermissions完整reason) - [ ] 应用内隐私政策可达,逐项对应权限用途
- [ ] 第三方 SDK 名单与用途说明
包体/兼容
- [ ] 仅包含需要的 ABI
- [ ] 大资源做外置或按需下载
- [ ] 真机冒烟通过(冷启动、主要流程、后台前台切换)
商店素材
- [ ] 名称、简介、关键词不涉敏感词
- [ ] 截图/视频和实际功能一致
- [ ] 年龄分级、分类正确;UGC 有治理说明
结语:发布不是“临门一脚”,是“工程化终点站”
写到这,你应该已经能把HAP/APP 的关系说清楚,把签名从“玄学”拉回“配置”,把发布规范从“迷雾”变成“清单”。别忘了,真正让你发版变轻松的,不是今天运气好,而是流程脚本化 + 清单常态化 + 证书托管制度化。
下一次点下「提交审核」的时候,愿你心态稳得像早八地铁上的扶手:摇,但不慌。🚀
🧧福利赠与你🧧
无论你是计算机专业的学生,还是对编程有兴趣的小伙伴,都建议直接毫无顾忌的学习此专栏「滚雪球学SpringBoot」专栏(全网一个名),bug菌郑重承诺,凡是学习此专栏的同学,均能获取到所需的知识和技能,全网最快速入门SpringBoot,就像滚雪球一样,越滚越大, 无边无际,指数级提升。
最后,如果这篇文章对你有所帮助,帮忙给作者来个一键三连,关注、点赞、收藏,您的支持就是我坚持写作最大的动力。
同时欢迎大家关注公众号:「猿圈奇妙屋」 ,以便学习更多同类型的技术文章,免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板、技术文章Markdown文档等海量资料。
✨️ Who am I?
我是bug菌(全网一个名),CSDN | 掘金 | InfoQ | 51CTO | 华为云 | 阿里云 | 腾讯云 等社区博客专家,C站博客之星Top30,华为云多年度十佳博主/价值贡献奖,掘金多年度人气作者Top40,掘金等各大社区平台签约作者,51CTO年度博主Top12,掘金/InfoQ/51CTO等社区优质创作者;全网粉丝合计 30w+;更多精彩福利点击这里;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试真题、4000G PDF电子书籍、简历模板等海量资料,你想要的我都有,关键是你不来拿。

-End-
- 点赞
- 收藏
- 关注作者
评论(0)