鸿蒙开发笔记-9-应用状态管理:LocalStorage、AppStorage与PersistentStorage

34 阅读4分钟

一、基本概念

1. LocalStorage(页面级内存存储)

  • 专为单个UIAbility或页面组件树设计,支持通过@Entry装饰器在根节点分配实例,子组件自动继承访问权限
  • 生命周期:与页面绑定,最后一个引用释放时由JS引擎回收,组件树销毁时自动回收
  • 实现原理:每个页面独立维护,销毁时自动清除(API Version 11+支持跨页面持久化)
  • 同步机制:
    • @LocalStorageProp:单向绑定(父→子),适用于展示型数据
    • @LocalStorageLink:双向绑定(实时联动),适合需要联动的交互场景(如实时表单)

2. AppStorage(应用级全局状态池)

  • 应用进程内全局状态中枢,支持跨Ability/页面共享,与PersistentStorage/Environment形成生态联动
  • 生命周期:与进程绑定,应用启动时创建,退出时销毁(内存数据),但通过PersistentStorage可持久化
  • 实现原理:单例模式设计,通过装饰器实现UI组件与状态变量的双向/单向绑定
  1. 初始化策略:
    • AppStorage.SetOrCreate('theme', 'dark') 实现懒加载式初始化
    • 支持复杂对象存储(需配合@Observed装饰器)
  2. 访问方式:
    • @StorageProp:单向绑定(适合全局配置读取)
    • @StorageLink:双向绑定(如用户登录状态全局同步)
  • 核心特性:
    • 支持复杂类型(Map/Set/Date等,需配合@Observed装饰器)
    • 提供connect API实现类型安全的状态访问
    • 与PersistentStorage深度集成
    • 仅支持主线程访问,非UI线程需通过Worker线程处理
    • 避免存储超过2MB的大型对象
    • 高频更新数据建议配合@Trace装饰器使用

3. PersistentStorage(持久化存储引擎)

  • 应用级持久化数据保险库,实现"重启不丢失"的数据持久
  • 实现原理:基于JSON序列化的磁盘存储机制,通过观察者模式监听数据变更
  • 生命周期:数据永久存储于设备磁盘,需通过AppStorage中转操作
  • 关键技术
    • 类型白名单(支持number/string/boolean/enum/Map/Set/Date)
    • 异步持久化队列(默认2KB/次写入)
    • 增量更新机制(仅同步变更数据)
  • 典型场景:用户偏好设置、离线缓存

二、对比分析

维度LocalStorageAppStoragePersistentStorage
存储位置内存(页面级)内存(应用级)磁盘(持久化)
数据类型简单类型+可序列化对象复杂类型(需@Observed简单类型+部分复杂类型
同步方式单向/双向(内存操作)双向(内存操作)异步持久化(磁盘IO)
安全风险内存泄露风险数据泄露/篡改风险
典型延迟μs级μs级ms级(磁盘写入)
适用场景临时状态、页面间通信全局状态共享配置数据、历史记录

三、使用场景

1. LocalStorage
  • 页面内多组件状态共享
  • 动态样式切换(主题/布局)
  • 表单数据临时存储
  • 示例:
typescript
// 页面级主题管理
const storage = new LocalStorage({ 'theme': 'light' });

@Entry(storage)
@Component struct ThemePage {
  @LocalStorageLink('theme') currentTheme: string = 'light'
  
  build() {
    Column() {
      ThemeSwitcher({ theme: $$this.currentTheme })
      ContentArea()
    }.backgroundColor(this.currentTheme === 'dark' ? '#333' : '#FFF')
  }
}
2. AppStorage
  • 用户全局偏好设置
  • 跨Ability数据共享
  • 应用级状态管理(如登录态)
  • 示例:
typescript
// 全局登录状态管理
AppStorage.setOrCreate('isLoggedIn', false)

@Entry
@Component struct MainEntry {
  @StorageLink('isLoggedIn') isLogin: boolean = false

  build() {
    Column() {
      if (this.isLogin) {
        HomePage()
      } else {
        LoginPage()
      }
    }
  }
}

关键特性

  • 类型推断与编译时校验
  • 支持嵌套对象(需确保属性可序列化)
3. PersistentStorage
  • 需要持久化的用户设置
  • 离线缓存关键数据
  • 应用配置信息存储
  • 示例:
typescript
// 持久化用户设置
PersistentStorage.persistProp('userSettings', {
  fontSize: 14,
  notification: true
})

@Entry
@Component struct SettingsPage {
  @StorageLink('userSettings') settings: any = {}

  changeFontSize(size: number) {
    this.settings.fontSize = size
  }
}
4. PersistentStorage加密方案
// 静态数据加密(AES-256)
import { cryptoFramework } from '@ohos.security.crypto';

async function securePersist(key: string, value: string) {
  const cipher = await cryptoFramework.createCipher('AES128|ECB|PKCS7', 'your-secret-key');
  const encrypted = cipher.encrypt(value);
  PersistentStorage.persistProp(key, encrypted);
}

安全建议

  • 敏感数据必须加密(推荐AES-256)
  • 结合哈希算法验证数据完整性
5. PersistentStorage状态更新策略
typescript
// 推荐更新方式
class UpdateService {
  static updateGlobalState(key: string, value: any) {
    if (needPersist(key)) {
      PersistentStorage.persistProp(key, value)
    }
    AppStorage.setOrCreate(key, value)
  }
}
6. 状态恢复与容灾
// 应用启动时数据校验
windowStage.loadContent('pages/Index', async (err) => {
  if (err) {
    console.error('Failed to load content:', err);
    return;
  }
  const lastData = await PersistentStorage.get('criticalData');
  if (!lastData) {
    // 从云端备份恢复
    const backup = await fetchBackup();
    PersistentStorage.persistProp('criticalData', backup);
  }
});

容灾策略

  • 关键数据双重存储(本地+云端)
  • 定期测试备份恢复流程

四、总结

  • 优先使用LocalStorage处理页面级状态
  • 需要跨页面共享时升级到AppStorage
  • 对关键配置数据使用PersistentStorage持久化
  • 对于高频更新数据,建议使用AppStorage+内存缓存组合;对于敏感数据,必须启用加密与完整性校验。

我是今阳,如果想要进阶和了解更多的干货,欢迎关注微信公众号 “今阳说” 接收我的最新文章