HarmonyOS 7 Preferences + AppStorage:配置 Schema 升级中的分步迁移、失败回滚与多页面状态同步【鸿蒙心迹】
这次处理版本升级后的配置问题。SettingsMigrationLab在 3.1.x 里把字号保存成整数百分比例如100、115到了 3.2.0我想统一成1.0、1.15同时补上theme、compactMode等字段。第一次实现时我直接读旧值、覆盖新值。测试中途故意抛异常后首页已经读到新字段列表页仍拿着旧 AppStorage 值Preferences 里也只改了一半。应用能启动却处在“表面正常、配置已经分叉”的状态。这篇只解决一个问题Schema 从 2 升级到 3 时怎样把迁移拆成可以验证、可以回滚并且一次性同步到多个页面。一、先给配置一个明确版本最终数据固定为cfg_20261001_11、3.2.0(30200)、Schema2→3、MIGRATED、Migrated Keys6、Rollback Count1、Pages Synced3、Themesystem、Font Scale1.15、Last Migration10:54:32。没有schemaVersion时“某个字段有没有”不能说明用户从哪个版本升级上来所以明确保存schemaVersion 3 migrationState MIGRATED以后升级走显式版本路径。二、迁移前先做快照第一段代码解决中途失败。import { preferences } from kit.ArkData private async createSnapshot( prefs: preferences.Preferences, snapshotId: string ): PromiseRecordstring, preferences.ValueType { const keys: string[] [ schemaVersion, theme, fontScalePct, fontScale, compactMode, migrationState ] const snapshot: Recordstring, preferences.ValueType {} for (const key of keys) { snapshot[key] await prefs.get(key, __MISSING__) } await prefs.put( snapshot:${snapshotId}, JSON.stringify(snapshot) ) await prefs.flush() return snapshot }我只保存这次会改到的字段。__MISSING__表示旧版本没有这个 key回滚时应该删除。三、迁移、验证、版本落盘必须有顺序2→3 迁移里schemaVersion最后才写。private async migrateV2ToV3( prefs: preferences.Preferences ): Promisevoid { await prefs.put(migrationState, MIGRATING) await prefs.flush() const oldPct Number(await prefs.get(fontScalePct, 100)) const fontScale Number((oldPct / 100).toFixed(2)) await prefs.put(fontScale, fontScale) await prefs.put( theme, await prefs.get(theme, system) ) await prefs.put( compactMode, await prefs.get(compactMode, false) ) await prefs.delete(fontScalePct) const theme String(await prefs.get(theme, system)) if (fontScale 0.8 || fontScale 1.6) { throw new Error(invalid fontScale: ${fontScale}) } if (![system, light, dark].includes(theme)) { throw new Error(invalid theme: ${theme}) } await prefs.put(schemaVersion, 3) await prefs.put(migrationState, MIGRATED) await prefs.flush() }如果开头就把schemaVersion写成 3后面失败下次启动可能误以为升级结束。本次字号115最终转成1.15主题没有用户值时使用system旧字段fontScalePct在验证通过后删除。Demo 第一次校验故意失败因此最终Rollback Count1。四、回滚要恢复旧值也要恢复“原来没有”我之前踩过的坑是只把fontScalePct写回去却忘了删除已经创建的fontScale。下一次启动时两套字段同时存在代码到底读哪个又成了新问题。所以restoreSnapshot()会遍历快照普通值用put()恢复值为__MISSING__的字段执行delete()随后把rollbackCount加 1、把migrationState写成ROLLED_BACK最后统一flush()。这一步的重点不是“恢复几个数字”而是把整个 Schema 恢复到迁移前可解释的状态。五、只有 MIGRATED 以后才同步 AppStoragePreferences 是持久化配置AppStorage 是页面运行态。迁移进行到一半时不应该交替更新两边。private async publishRuntimeState( prefs: preferences.Preferences ): Promisevoid { const theme String(await prefs.get(theme, system)) const fontScale Number(await prefs.get(fontScale, 1.0)) AppStorage.setOrCreatestring(theme, theme) AppStorage.setOrCreatenumber(fontScale, fontScale) AppStorage.setOrCreatestring( settingsSchemaState, MIGRATED ) this.pagesSynced 3 }首页、列表页和“我的”页都订阅同一份运行态最终三个页面统一为themesystem、fontScale1.15。迁移成功后由桥接层一次性发布页面只订阅 AppStorage。六、日志必须能复原迁移路径工程中EntryAbility只负责启动迁移SettingsMigrationService负责版本判断、验证和回滚SettingsStateBridge只在成功后同步 AppStorage。HiLog 固定保留schema 2 - 3 snapshotcfg_20261001_11 migratedKeys6 rollbackCount1 pagesSynced3 State: MIGRATING - MIGRATED线上出现问题时先看 schema 路径和 snapshotId。七、运行结果要看页面是否收敛最终手机界面显示cfg_20261001_11、3.2.0(30200)、2→3、MIGRATED、Migrated Keys6、Rollback Count1、Pages Synced3、Themesystem、Font Scale1.15、Last Migration10:54:32。下方三个状态卡代表首页、列表页和“我的”页都显示SYNCED。Schema 升级真正结束的条件是持久层通过验证、运行态已发布、页面也完成收敛。八、重复启动和跨版本升级必须幂等schema 已经是 3 时直接退出不能每次启动都重复创建快照。如果用户从 schema 1 直接升级到 3我会按1→2→3分步执行每一步独立验证和回滚。迁移中应用被终止时下次启动根据migrationStateMIGRATING恢复快照或重新执行。九、配置很轻升级过程却不能靠运气流程固定为SNAPSHOT → MIGRATING → VALIDATING → MIGRATED失败路径MIGRATING → ERROR → ROLLED_BACK → RETRY页面同步只发生在MIGRATED之后。Preferences 不复杂真正需要设计的是升级中的时间顺序。把持久化迁移和运行态发布拆开后就不会因为某个页面先启动或一次异常而留下半套新数据。

相关新闻

AI工业控制系统搭建实战:从架构设计到边缘部署

AI工业控制系统搭建实战:从架构设计到边缘部署

1. 从零理解AI工业控制系统的核心架构1.1 为什么传统工控需要AI介入干了十多年工业自动化,我见过太多产线还在用"if-else"逻辑硬扛复杂工况。传统PLC和DCS系统擅长处理确定性任务——比如温度到了80度就开阀,压力超过阈值就报警。但现实生产里…

2026/10/4 7:31:02 阅读更多 →
Go Web 编程实战:用 `os` 包完成文件与目录操作(基于 build-web-application-with-golang 第 7.5 节)

Go Web 编程实战:用 `os` 包完成文件与目录操作(基于 build-web-application-with-golang 第 7.5 节)

文档教程 【免费下载链接】build-web-application-with-golang A golang ebook intro how to build a web with golang 项目地址: https://gitcode.com/gh_mirrors/bu/build-web-application-with-golang 点击查看 免费下载 文件是每一台计算机上的基本对象&#x…

2026/10/4 7:30:01 阅读更多 →
2026年10月上海名义人擅自转让律师推荐|李超律师团队

2026年10月上海名义人擅自转让律师推荐|李超律师团队

代持的股权被名义股东"悄悄卖掉",实际出资人(或其配偶)能不能追回?一句话结论:名义股东属无权处分,受让人善意与否决定结局——真实出资人能证明代持关系且受让人非善意的,可主张转让…

2026/10/4 7:30:01 阅读更多 →

最新新闻

ANOVA、T检验、卡方检验如何选?三步决策法

ANOVA、T检验、卡方检验如何选?三步决策法

1. 这不是“选哪个公式”的问题,而是“你到底在问什么”的问题刚带完一个数据分析新人的实操训练营,有个学员举手问:“老师,我该用ANOVA还是T检验?SPSS里点哪个按钮?”——那一刻我就知道,他还没…

2026/10/4 8:31:46 阅读更多 →
HarmonyOS端侧视觉AI实践:人脸检测与OCR两步接入全解析

HarmonyOS端侧视觉AI实践:人脸检测与OCR两步接入全解析

1. 项目定位与整体思路:为什么"两步接入"是最务实的姿势如果你最近在 HarmonyOS 7 上做视觉 AI 相关功能,八成绕不开两个再常见不过的诉求:让 App 认出画面里的人,再让 App 读出画面里的字。人脸检测和通用文字识别&…

2026/10/4 8:31:46 阅读更多 →
Symfony Resend Mailer Bridge 完整实战指南:DSN 配置、RemoteTemplateEmail 远程模板与 Webhook 事件解析

Symfony Resend Mailer Bridge 完整实战指南:DSN 配置、RemoteTemplateEmail 远程模板与 Webhook 事件解析

后端Web框架 【免费下载链接】symfony The Symfony PHP framework 项目地址: https://gitcode.com/GitHub_Trending/sy/symfony 点击查看 免费下载 Resend 是面向开发者的邮件发送服务,Symfony Mailer 通过 symfony/resend-mailer Bridge 提供与 Resend…

2026/10/4 8:31:46 阅读更多 →
终端窗口开太多之后,我把 Claude Code 和 Codex 都丢给了 Paseo

终端窗口开太多之后,我把 Claude Code 和 Codex 都丢给了 Paseo

说真的,如果你电脑里同时装着 Claude Code 和 Codex,大概率经历过这种场面:左边终端跑着 Codex,右边 Claude Code 在等权限确认,下面还有一个 OpenCode 不知道卡在哪。切来切去,最后忘了哪个窗口是干嘛的。…

2026/10/4 8:31:46 阅读更多 →
开源 WMS 合规交付实务:JeeWMS 仓库管理系统在 GPL-3.0 下的源码台账与交付清单

开源 WMS 合规交付实务:JeeWMS 仓库管理系统在 GPL-3.0 下的源码台账与交付清单

> 选题编号:23(30 选题轮换 GPL-3.0 合规)## 一、合规问题不是在法务室被问出来的,是在交付现场被问出来的很多团队第一次被协议"绊住",不是在选型阶段读 LICENSE,而是在项目交付现场&#x…

2026/10/4 8:31:46 阅读更多 →
校园拼车系统实战:Java + 微信小程序全栈开发与高并发避坑指南

校园拼车系统实战:Java + 微信小程序全栈开发与高并发避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 8:30:46 阅读更多 →

日新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 10:36:31 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/3 9:42:35 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/3 9:42:36 阅读更多 →