【私房菜集 HarmonyOS ArkTS 实战系列 14】发布前质量复盘:module.json5、资源、备份扩展与构建验收
【私房菜集 HarmonyOS ArkTS 实战系列 14】发布前质量复盘:module.json5、资源、备份扩展与构建验收
从第 01 篇到第 13 篇,私房菜集已经完成工程骨架、数据资产、首页推荐、搜索、详情、收藏、添加菜谱、计时器、偏好、设置、分享和桌面卡片。本篇做系列收官,不再只看某一个页面,而是回到可发布项目的最后一公里:资源、启动体验、备份扩展、配置边界、构建检查和文章交付质量。

一、可发布项目不只看功能
一个 HarmonyOS 项目能运行,不等于能发布;页面可点击,也不等于工程完整。真正交付前还要看这些问题:
- 应用名称、图标、启动图是否仍是模板资源。
- 明暗主题资源是否完整,启动窗口是否跟随主题。
module.json5中 ability 和 extension ability 是否注册正确。- 备份配置是否明确表达允许备份恢复。
- 桌面卡片配置是否和源码入口一致。
- 关于页展示版本是否和包配置保持一致。
- 构建产物是否能稳定生成。
- 对外文章是否有真实截图、代码、验证和复盘。
这一篇把这些点串起来,形成系列最后的工程质量清单。
二、源码对象总览
| 源码对象 | 作用 |
|---|---|
entry/src/main/module.json5 |
应用模块配置,声明 EntryAbility、BackupExtensionAbility、FormExtensionAbility。 |
entry/src/main/ets/entryability/EntryAbility.ets |
启动主题、启动窗口背景、卡片跳转处理。 |
entry/src/main/ets/entrybackupability/EntryBackupAbility.ets |
备份恢复扩展能力。 |
resources/base/profile/backup_config.json |
声明是否允许备份恢复。 |
resources/base/profile/form_config.json |
声明桌面卡片配置。 |
resources/base/element/color.json |
浅色资源。 |
resources/dark/element/color.json |
深色资源。 |
pages/AboutPage.ets |
关于页和版本信息展示。 |
build-profile.json5 |
构建配置入口。 |
这些文件不一定每天改,但它们决定项目是否像一个完整应用,而不是只像页面 Demo。
三、发布前总览:从页面验收到工程验收
收官检查要从“页面可打开”继续推进到配置、资源、状态、系统能力和文章交付。可以先建立一张总图:

这张图对应六组验收对象:
| 验收对象 | 关键问题 |
|---|---|
module.json5 |
主 Ability、备份扩展、表单扩展是否注册完整。 |
| 资源目录 | 图标、启动图、明暗资源是否成对存在。 |
| 本地状态 | Preferences、自建菜谱、计时器会话是否能持久化。 |
| 系统能力 | 图库保存、桌面卡片、备份扩展是否有真实配置。 |
| 构建验收 | HAP 能否稳定生成,模拟器/真机能否启动。 |
| 文章交付 | 封面、正文图、代码、验证清单和复盘是否齐全。 |
本篇复盘对应的实测环境如下:
| 项目 | 实测值 |
|---|---|
| 项目名称 | MyApplicationSFCJ |
| 应用名称 | 私房菜集 |
| 应用包名 | com.lesson.myapplicationsfcj |
| 包配置版本 | AppScope/app.json5 -> versionName: 1.0.1, versionCode: 1000000 |
| 模块名称 | entry |
| 模块类型 | entry |
| 设备类型 | phone |
| SDK 版本 | targetSdkVersion: 6.1.0(23), compatibleSdkVersion: 6.0.2(22) |
| 工程模型 | modelVersion: 6.1.0, apiType: stageMode |
| 运行设备 | 本地 HarmonyOS 模拟器 |
| 质量复核日期 | 2026-07-06 |
下面逐项拆这些对象。
四、module.json5:应用能力注册总入口
module.json5 中主模块声明为 entry:
{
"module": {
"name": "entry",
"type": "entry",
"mainElement": "EntryAbility",
"deviceTypes": [
"phone"
],
"deliveryWithInstall": true,
"installationFree": false,
"pages": "$profile:main_pages",
...
}
}
这里有几个发布前核对点:
type是entry,代表主入口模块。deviceTypes包含phone,和当前 UI 设计目标一致。pages指向main_pages,页面注册由 profile 文件统一维护。installationFree为false,当前不是免安装应用。
这些配置如果和实际项目不一致,运行时可能表现正常,但发布审核或安装体验会出现问题。
五、EntryAbility:启动体验和外部跳转入口
EntryAbility 负责的不只是加载首页。它在 onCreate() 中做了本地存储初始化、主题恢复和卡片参数处理:
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
try {
localStoreAdapter.init(this.context);
settingsService.applySavedTheme(this.context);
this.handleCardRouterWant(want);
} catch (err) {
hilog.error(DOMAIN, 'testTag',
'Failed to set colorMode. Cause: %{public}s',
JSON.stringify(err));
}
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
}
在 onWindowStageCreate() 中,它还设置启动窗口背景:
const LIGHT_START_WINDOW_BG = '#FFF0DF';
const DARK_START_WINDOW_BG = '#151311';
const themeMode = settingsService.getSettings().themeMode;
const backgroundColor = themeMode === 'dark'
? DARK_START_WINDOW_BG
: LIGHT_START_WINDOW_BG;
windowStage.getMainWindowSync().setWindowBackgroundColor(backgroundColor);
这一步能避免深色模式下启动瞬间出现浅色闪屏。第 12 篇已经拆过主题链路,收官时要把它纳入发布检查。
六、启动资源:图标和启动页不能是模板
module.json5 中主 Ability 声明了图标、名称和启动图:
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"description": "$string:EntryAbility_desc",
"icon": "$media:app_icon",
"label": "$string:EntryAbility_label",
"startWindowIcon": "$media:splash_screen",
"startWindowBackground": "$color:start_window_background",
"exported": true
}
发布前逐项确认:
app_icon不是默认模板图标。splash_screen能体现“私房菜集”应用气质。EntryAbility_label与桌面显示名称一致。start_window_background在浅色和深色资源中都有对应值。
资源检查不是形式主义。用户第一次启动时看到的就是图标、名称和启动页,它们会直接影响应用完成度感知。
七、明暗资源:语义颜色要成对存在
浅色资源中有:
{
"name": "app_bg",
"value": "#FFFBF5"
},
{
"name": "card_bg",
"value": "#FFFFFF"
},
{
"name": "primary_orange",
"value": "#F57C22"
}
深色资源中有:
{
"name": "app_bg",
"value": "#151311"
},
{
"name": "card_bg",
"value": "#24211E"
},
{
"name": "primary_orange",
"value": "#FF8A32"
}
发布前逐项检查两个目录下的资源 key 是否成对。浅色有 danger_red、success_green,深色目录也保留对应值,页面切换到深色时可以稳定解析并保持一致显示。
八、备份扩展:先注册能力,再逐步填充内容
项目里已经声明了备份扩展:
{
"name": "EntryBackupAbility",
"srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets",
"type": "backup",
"exported": false,
"metadata": [
{
"name": "ohos.extension.backup",
"resource": "$profile:backup_config"
}
]
}
backup_config.json 很简洁:
{
"allowToBackupRestore": true
}
扩展能力本身如下:
export default class EntryBackupAbility extends BackupExtensionAbility {
async onBackup() {
hilog.info(DOMAIN, 'testTag', 'onBackup ok');
await Promise.resolve();
}
async onRestore(bundleVersion: BundleVersion) {
hilog.info(DOMAIN, 'testTag',
'onRestore ok %{public}s',
JSON.stringify(bundleVersion));
await Promise.resolve();
}
}
当前实现是最小可用骨架:能力注册齐全,配置允许备份恢复,生命周期有日志。后续如果要真正备份用户菜谱、收藏、偏好和笔记,需要进一步明确 Preferences 文件和自建菜谱 JSON 的备份范围。
九、桌面卡片:配置和扩展能力要对应
module.json5 中还注册了表单扩展:
{
"name": "EntryFormAbility",
"srcEntry": "./ets/entryformability/EntryFormAbility.ets",
"label": "$string:EntryFormAbility_label",
"description": "$string:EntryFormAbility_desc",
"type": "form",
"metadata": [
{
"name": "ohos.extension.form",
"resource": "$profile:form_config"
}
]
}
对应 form_config.json 中的 src 是:
"src": "./ets/widget/pages/WidgetCard.ets"
发布前要核对三件事:
EntryFormAbility的name和 module 注册一致。form_config.json的src指向真实存在的WidgetCard.ets。WidgetCard里的LocalStorageProp字段和EntryFormAbility返回的RecipeWidgetData字段一致。
这种配置链路一旦拼错,主应用可能仍能运行,但桌面卡片不可添加或无法刷新。
十、关于页:包版本 1.0.1 与展示版本核对
关于页展示了应用名称、版本和定位。包配置中的正式版本来自 AppScope/app.json5:
{
"versionCode": 1000000,
"versionName": "1.0.1"
}
当前关于页源码展示如下:
Text('私房菜集')
.fontSize(28)
.fontWeight(FontWeight.Bold)
.fontColor($r('app.color.primary_orange'))
Text('版本 1.0.1')
.fontSize(14)
.fontColor($r('app.color.text_secondary'))
Text('一个本地优先、离线可用的菜谱应用,用来浏览、搜索、收藏和记录自己的下厨灵感。')
.fontSize(15)
.fontColor($r('app.color.text_primary'))
.lineHeight(24)
.textAlign(TextAlign.Center)
截图中关于页处于深色模式,同时覆盖第 12 篇的资源切换和 versionName: 1.0.1 展示。

十一、页面注册:14 个页面要能形成闭环
规划阶段确认项目使用 main_pages.json 注册页面,并通过 AppRoutes.ets 集中维护路由。收官时需要检查这些页面是否都在工程中存在:
export class AppRoutes {
static readonly INDEX: string = 'pages/Index';
static readonly DETAIL: string = 'pages/RecipeDetailPage';
static readonly SEARCH: string = 'pages/SearchResultPage';
static readonly CATEGORY: string = 'pages/CategoryRecipeListPage';
static readonly ADD_RECIPE: string = 'pages/AddRecipePage';
static readonly TIMER: string = 'pages/TimerPage';
static readonly NOTE: string = 'pages/NotePage';
static readonly DIET_PREFERENCE: string = 'pages/DietPreferencePage';
static readonly SETTINGS: string = 'pages/SettingsPage';
static readonly SHARE: string = 'pages/ShareRecipePage';
static readonly UNIT_CONVERTER: string = 'pages/UnitConverterPage';
static readonly BACKUP_RESTORE: string = 'pages/BackupRestorePage';
static readonly PRIVACY_DATA: string = 'pages/PrivacyDataPage';
static readonly ABOUT: string = 'pages/AboutPage';
}
路由集中管理的好处是显而易见的:标题、按钮、服务层不需要散落写页面字符串,后续改页面路径时也更容易定位。
十二、构建前质量检查
项目交付前完成下面几类检查:
| 检查项 | 验收标准 |
|---|---|
| 应用启动 | 能进入首页,底部四 Tab 正常切换。 |
| 数据加载 | 15 个分类、514 道菜可读,图片资源可显示。 |
| 详情链路 | 菜谱详情、用料、步骤、收藏、想做、计时器可用。 |
| 本地状态 | 收藏、想做、最近浏览、笔记、偏好、主题能持久化。 |
| 主题模式 | 跟随系统、浅色、深色切换后页面可读。 |
| 添加菜谱 | 表单校验、图片选择、保存和详情跳转正常。 |
| 分享能力 | 分享页能生成卡片并保存到图库。 |
| 桌面卡片 | 卡片可添加、可刷新、可点击回详情。 |
| 备份扩展 | 配置可读,扩展能力注册正确。 |
| 关于页 | 应用名称、版本和描述与包配置一致。 |
构建命令可以使用项目根目录下的 Hvigor 任务,例如:
hvigorw :entry:assembleHap
本次复盘在 DevEco Studio 中完成全量构建检查,HAP 产物可以稳定生成。
本次复盘已经完成的运行侧证据如下:
| 证据 | 文件 |
|---|---|
| 关于页深色截图 | SFCJ/screenshots/14_about_dark_raw.jpeg |
| 关于页 UI 树 | SFCJ/screenshots/14_about_dark_layout.json |
| 设置页深色截图 | SFCJ/screenshots/12_settings_dark_raw.jpeg |
| 设置页 UI 树 | SFCJ/screenshots/12_settings_dark_layout.json |
| 包信息查询 | hdc shell bm dump -n com.lesson.myapplicationsfcj |
| 包配置版本 | versionName: 1.0.1, versionCode: 1000000 |
| 扩展能力 | EntryBackupAbility、EntryFormAbility |
十三、发布前可执行命令清单
如果要把收官检查落到执行层,可以按下面顺序跑:
# 1. 检查模块配置和页面注册
hvigorw :entry:assembleHap
# 2. 安装到模拟器或真机后检查包信息
hdc shell bm dump -n com.lesson.myapplicationsfcj
# 3. 检查运行时 UI 树,确认当前页面和文字
hdc shell uitest dumpLayout
# 4. 截取真实运行图,用于发布记录和文章复核
hdc shell snapshot_display -f /data/local/tmp/sfcj_check.jpeg
这几条命令分别对应构建、包配置、页面可访问性和截图复核。配合人工验收记录,可以把发布检查固化为可追溯流程。
十四、CSDN 系列文章交付标准
这个系列不是简单“功能介绍”,每篇文章都应该满足以下标准:
- 标题统一:
【私房菜集 HarmonyOS ArkTS 实战系列 NN】主题:副标题。 - 开头承接上一篇,说明本篇解决的工程问题。
- 正文必须包含真实 App 截图,截图不能长期复用同一张首页图。
- 正文必须包含真实源码对象和关键代码片段。
- 不能只讲 UI,要讲页面、服务、仓储、模型之间的数据流。
- 每篇都要有运行验证和问题复盘。
- 封面要使用真实应用截图,主题词和篇序清晰。
- 草稿箱保存后必须反查封面和正文图片是否真正上传成功。
- 文章中不能出现创作过程说明、生成过程说明、占位语句。
这套标准贯穿 14 篇文章,能保证读者看到的是完整工程拆解,而不是松散笔记。
十五、系列总复盘
14 篇文章可以分成五条主线。
第一条是工程骨架:Stage 模型、entry 模块、页面注册、底部 Tab 和路由常量。
第二条是内容资产:rawfile/dishes/dishes.json、图片资源、模型映射、分类和详情消费。
第三条是核心浏览:首页推荐、探索搜索、分类列表、详情页、用料步骤和随机厨房。
第四条是本地状态:收藏、想做、最近浏览、笔记、饮食偏好、主题模式和计时器会话。
第五条是系统能力:相册选择、保存到图库、桌面卡片、备份扩展、启动窗口和发布资源。
从一个单机菜谱应用出发,这个项目覆盖了 HarmonyOS ArkTS 应用开发中很典型的一组能力:页面组织、资源管理、本地 JSON 数据源、Preferences 持久化、系统组件、扩展 Ability 和发布前质量检查。
十六、收官小结
私房菜集的价值不在于“有多少页面”,而在于它把菜谱应用常见能力连成了一个闭环:
内容资产 -> 首页/搜索/详情 -> 收藏/想做/笔记/偏好
-> 添加菜谱/计时器/分享
-> 设置/主题/卡片/备份
-> 发布前质量检查
一个可发布项目的完成度,最终体现在这些边界是否清晰、状态是否可靠、截图是否真实、配置是否闭环。到这里,私房菜集 HarmonyOS ArkTS 实战系列 14 篇文章完成收束。
更多推荐



所有评论(0)