← 回總覽

ArkTS 用 Preferences 存 App 配置的正确姿势 —— 从踩坑到 singleton 封装

📅 2026-07-25 09:15 SameX 软件编程 2 分鐘 2125 字 評分: 88
HarmonyOS 数据持久化 Singleton 移动开发 TypeScript
📌 一句话摘要 本文分享 HarmonyOS 项目中使用 Preferences 存储 App 配置的最佳实践,从原生 API 的痛点出发,逐步演进为 singleton + sync API + 静默失败 + schema migration 的完整封装方案。 📝 详细摘要 作者以自身项目 breathing 中多语言持久化功能为起点,详细记录了使用 Preferences 存储配置时从直觉写法到生产级封装的完整思考过程。文章首先指出原生 API 的多个痛点:每次需要 async、到处传 context、返回值类型不安全、对象序列化重复代码、字符串常量散落等。然后围绕五个关键决策展开:1

📌 一句话摘要

本文分享 HarmonyOS 项目中使用 Preferences 存储 App 配置的最佳实践,从原生 API 的痛点出发,逐步演进为 singleton + sync API + 静默失败 + schema migration 的完整封装方案。

📝 详细摘要

作者以自身项目 breathing 中多语言持久化功能为起点,详细记录了使用 Preferences 存储配置时从直觉写法到生产级封装的完整思考过程。文章首先指出原生 API 的多个痛点:每次需要 async、到处传 context、返回值类型不安全、对象序列化重复代码、字符串常量散落等。然后围绕五个关键决策展开:1)全局 singleton 而非各模块独立持有,以控制初始化和 IO 成本;2)弃用 async 版 API,选用 sync 版(putSync/flushSync),因为 Preferences 操作基于内存 map,sync 版本省去 Promise 开销且不阻塞 UI;3)每个 getter 做 typeof 严格检查并返回 fallback,践行「静默失败哲学」—— 配置读取失败绝不让 App 挂掉;4)复杂对象全部序列化为 JSON 字符串走 setString/getString,保证可预测、可迁移、跨平台兼容;5)引入 schemaVersion + 迁移类 AppDataMigration,确保老用户升级时不会因字段变更而 crash 或丢数据。封装后的业务代码变成一行同步调用,无需关心 async、异常和 context。文章还解答了常见疑问:为何不用 dataAbility、崩溃时数据安全、iOS 版心智复用、性能影响等。最后给出三条建议:封装 singleton、优先用 sync、第一天就上 migration。

💡 主要观点

- 全局 singleton 持有一个 Preferences 实例,避免重复 IO 和不可控的初始化时机。 每个模块自己 getPreferences 会导致多次文件 IO 和异步依赖;全局 singleton 在 App 启动阶段 init,之后所有读写同步且无需传 context。

同步 API(putSync/flushSync)比异步版本更适合配置读写场景。 Preferences 操作基于内存 map,get/put 本身无 IO,sync 版省去 Promise 开销且不会造成 async 传染;flush 虽阻塞线程但配置写入频率极低,毫秒级延迟可接受。
每个 getter 做严格类型检查并返回 fallback,践行「静默失败哲学」。 应对 schema 升级或手动改文件导致的类型不匹配,配置读取失败绝不 crash,最多回退默认值;通过日志埋点(而非 crash)来定位问题。
复杂对象序列化为 JSON 字符串存储,保证可预测、可迁移、跨平台。 避免依赖 Preferences 内置 object 存储的 SDK 兼容性;JSON 字符串未来可导出备份、直接查看、且与 iOS UserDefaults 场景对齐。
从第一天引入 schemaVersion + 迁移机制,保证老用户升级不 crash 不丢数据。 App 迭代中配置字段可能变更,迁移类在 bootstrap 阶段按版本号递增执行数据转换,上线后再补几乎不可能覆盖所有遗留数据。

💬 文章金句

- init 里那个 initializing 状态很重要 —— 如果多个地方并发调 init,我不希望重复 getPreferences,也不希望第二个 caller 拿不到实例。

  • 之后就改成了 put 完立刻 flush,宁愿多写几次盘,也不能让用户改完的设置丢。
  • 配置读取失败绝不能让 App 挂掉,最多是回到默认值。
  • 我推荐每个非玩具项目从第一天就上 schema version + migration 机制。上线之后再想加就晚了 —— 你不知道用户 Preferences 里都残留着什么祖传字段。

📊 文章信息

AI 初评:88

来源:掘金本周最热

作者:SameX

分类:软件编程

语言:中文

阅读时间:17 分钟

字数:4135

标签: HarmonyOS, 数据持久化, Singleton, 移动开发, TypeScript

阅读完整文章

查看原文 → 發佈: 2026-07-25 09:15:41 收錄: 2026-07-25 20:00:04

🤖 問 AI

針對這篇文章提問,AI 會根據文章內容回答。按 Ctrl+Enter 送出。