本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新

一、PersistentStorage 概述

PersistentStorage 是鸿蒙(HarmonyOS)应用设计中用于持久化存储UI状态的解决方案。它的核心作用是将选定的 AppStorage 属性持久化存储在设备磁盘上,以确保这些属性在应用程序重新启动时的值与应用程序关闭时的值相同。

核心特性:

  • 持久化存储:将 UI 状态数据保存在设备磁盘中,应用重启后数据不丢失。
  • 依赖 AppStorage:PersistentStorage 的持久化和数据读取能力都依赖于 AppStorage。
  • 双向同步:PersistentStorage 和 AppStorage 中的属性建立了双向同步关系。
  • UI/业务逻辑不直接访问:所有属性访问都是对 AppStorage 的访问,AppStorage 中的更改会自动同步到 PersistentStorage。

二、工作原理

PersistentStorage 的工作机制如下:

  1. 数据存储路径

    • PersistentStorage 的存储路径为 module 级别
    • 即哪个 module 调用了 PersistentStorage,数据就存入对应 module 的持久化文件中。
    • 如果多个 module 使用相同的 key,则数据归属到最先使用 PersistentStorage 的 module 中。
  2. 数据同步机制

    • PersistentStorage 将选定的 AppStorage 属性持久化到磁盘。
    • UI 和业务逻辑不直接访问 PersistentStorage,而是通过 AppStorage 进行数据读写。
    • AppStorage 中的数据变化会自动同步到 PersistentStorage,反之亦然。
  3. 启动时数据恢复

    • 应用启动时,PersistentStorage 会将磁盘中存储的数据读回 AppStorage,确保 UI 状态恢复。

三、使用限制

PersistentStorage 对数据类型和值的限制:

允许存储的类型:

  • 简单类型:numberstringbooleanenum 等。
  • 可被 JSON.stringify() 和 JSON.parse() 重构的对象。
  • 注意:对象中的成员方法不支持持久化。

不支持的类型:

  • 不支持嵌套对象或对象数组:即对象的属性仍然是对象,或数组元素为对象的情况。这会导致序列化失败或数据无法正确重构。
  • 不支持对象的成员方法:方法不会被持久化。
  • 复杂对象中如果包含无法序列化的成员,则整个对象无法持久化。

示例说明:

// 支持的类型
PersistentStorage.persistProp('score', 100); // number
PersistentStorage.persistProp('name', 'John'); // string
PersistentStorage.persistProp('isPassed', true); // boolean

// 不支持的类型:嵌套对象
PersistentStorage.persistProp('user', {
  name: 'John',
  address: { //嵌套对象,不支持!
    city: 'Beijing',
    street: 'Xinyuan Road'
  }
});

// 不支持的类型:对象数组
PersistentStorage.persistProp('users', [
  { name: 'John', age: 30 }, //对象数组,不支持!
  { name: 'Alice', age: 25 }
]);

四、注意事项

  1. 多模块数据冲突

    • 如果多个 module 使用相同的 key 调用 PersistentStorage,数据会归属到最先使用的 module,可能导致数据不一致。
  2. Ability 启动方式影响

    • 如果一个 Ability 被多个 module 拉起,则会产生多份数据副本,可能引发数据一致性问题。
  3. 推荐使用 PersistenceV2

    • PersistentStorage 在功能上耦合了 AppStorage,且在多模块使用中存在数据问题。
    • 推荐使用 PersistenceV2 的 globalConnect 接口替代 PersistentStorage 的 persistProp 接口。
    • 迁移方案详见官方链接:PersistentStorage → PersistenceV2

    4.持久化数据操作,应避免以下情况:

  1. 频繁写入:避免在短时间内多次调用 PersistentStorage.persistProp(),尤其是写入大量数据时。
  2. 大数据写入:避免持久化过大的对象或数组,会影响写入和读取性能。
  3. 主线程阻塞:持久化操作是同步的,如果在主线程中进行大量写入,可能会阻塞UI渲染,导致界面卡顿。
  4. PersistentStorage的持久化变量最好是小于2kb的数据。

五、其他

PersistentStorage 在鸿蒙状态管理体系中扮演“持久化中间件”的角色,与以下模块的关系如下:

UI组件 → AppStorage ↔ PersistentStorage → 磁盘文件
  • AppStorage:应用的全局 UI 状态存储中心,负责状态数据的运行时管理。
  • PersistentStorage:负责将 AppStorage 中指定的状态持久化到磁盘。
  • UI组件:通过 @StorageProp 或 @StorageLink 与 AppStorage 中的状态进行同步。

六、总结

项目 说明
作用 持久化存储 AppStorage 中的状态数据,确保应用重启后数据不丢失
同步机制 与 AppStorage 双向同步,UI不直接访问 PersistentStorage
存储路径 Module 级别,数据归属最先调用的 module
支持类型 简单类型、可序列化对象(不支持函数/方法)
推荐替代 PersistenceV2(globalConnect 接口)
使用场景 需要跨应用重启保留的UI状态,如用户设置、主题偏好等

建议在新项目中使用持久化存储,直接采用 PersistenceV2 方案。

Logo

为武汉地区的开发者提供学习、交流和合作的平台。社区聚集了众多技术爱好者和专业人士,涵盖了多个领域,包括人工智能、大数据、云计算、区块链等。社区定期举办技术分享、培训和活动,为开发者提供更多的学习和交流机会。

更多推荐