HarmonyOS NEXT鸿蒙的各种状态管理和持久化存储详解-根据场景选择

状态管理的种类

ArtTS提供了好几种状态用来帮助我们管理我们的全局数据

  • LocalStorage-UIAbility状态(内存- 注意:和前端的区分开,它非持久化,非全应用)
  • AppStorage- 全局应用内状态-多UIAbility共享-(内存-非持久化-退出应用同样消失)
  • PersistentStorage-持久化的全局应用内状态(写入磁盘-持久化状态-退出应用 数据同样存在)
  • Preferences首选项- 写入磁盘
  • 关系型数据库 - 写入磁盘
  • 端云数据库
  • 接口调用-云端数据(服务器数据)

API版本

LocalStorage  API 9+

AppStorage   API 11之后元服务也可使用

PersistentStorage API 12+ 支持的用法更全面

Preferences首选项 支持所有

状态管理对比

特性

LocalStorage

AppStorage

PersistentStorage

Preferences首选项

作用范围

页面级或 UIAbility 内

应用全局

应用全局 + 持久化

全局+持久化

存储位置

内存

内存

磁盘

内存或磁盘

生命周期

页面销毁时清除

应用退出时清除

长期保留(除非删除/卸载)

不调用flush在内存,调用后写入磁盘

数据同步机制

单向/双向组件绑定

单向/双向全局绑定

持久化的 AppStorage

get和put方法取值和修改值

典型应用场景

页面内状态共享

全局状态管理

需长期保存的关键数据

保存用户的个性化设置

UIAbility内状态-LocalStorage(我不常用)

LocalStorage 是页面级的UI状态存储,通过 @Entry 装饰器接收的参数可以在页面内共享同一个 LocalStorage 实例。 LocalStorage 也可以在 UIAbility 内,页面间共享状态。

用法

  • 创建 LocalStorage 实例:const storage = new LocalStorage({ key: value })
  • 单向 @LocalStorageProp('user') 组件内可变
  • 双向 @LocalStorageLink('user') 全局均可变

应用状态-AppStorage(重要)

LocalStorage是针对UIAbility的状态共享- 一个UIAbility有个页面

一个应用可能有若干个UIAbility

概述

AppStorage是在应用启动的时候会被创建的单例。它的目的是为了提供应用状态数据的中心存储,这些状态数据在应用级别都是可访问的。AppStorage将在应用运行过程保留其属性。属性通过唯一的键字符串值访问。

AppStorage可以和UI组件同步,且可以在应用业务逻辑中被访问。

AppStorage支持应用的主线程内多个UIAbility实例间的状态共享。

AppStorage中的属性可以被双向同步,数据可以是存在于本地或远程设备上,并具有不同的功能,比如数据持久化(详见PersistentStorage)。这些数据是通过业务逻辑中实现,与UI解耦,如果希望这些数据在UI中使用,需要用到@StorageProp@StorageLink

AppStorage 是应用全局的UI状态存储,是和应用的进程绑定的,由UI框架在应用程序启动时创建,为应用程序UI状态属性提供中央存储。-注意它也是内存数据,不会写入磁盘

第一种用法-使用UI修饰符

  • 如果是初始化使用 AppStorage.setOrCreate(key,value)
  • 单向 @StorageProp('user') 组件内可变
  • 双向 @StorageLink('user') 全局均可变

第二种用法 使用API方法

  • AppStorage.get<ValueType>(key) 获取数据
  • AppStorage.set<ValueType>(key,value) 覆盖数据

AppStorage.setOrCreate<T>("", T) // 创建或者设置某个字段的属性

AppStorage.get<T>("") // 获取的全局状态类型

如果遇到获取数据的类型为空,可以用if判断,也可以用非空断言来解决

StorageLink . - 直接修改-自动同步到全局状态

StorageProp- 可以改,只会在当前组件生效,只是改的全局状态的副本,不会对全局状态产生影响

状态持久化-PersistentStorage

前面讲的所有状态均为内存状态,也就是应用退出便消失,所以如果我们想持久化的保留一些数据,应该使用

PersistentStorage

注意:

UI和业务逻辑不直接访问 PersistentStorage 中的属性,所有属性访问都是对 AppStorage 的访问,AppStorage 中的更改会自动同步到 PersistentStorage

也就是,我们和之前访问AppStorage是一样的,只不过需要提前使用PersistentStorage来声明

PersistentStorage 将选定的 AppStorage 属性保留在设备磁盘上。

  • 支持:number, string, boolean, enum 等简单类型;
  • 如果:要支持对象类型,可以转换成json字符串
  • 持久化变量最好是小于2kb的数据,如果开发者需要存储大量的数据,建议使用数据库api。

用法:

PersistentStorage.PersistProp('属性名', 值)

注意: 如果用了持久化, 那么AppStorage读取出来的对象实际上是PersistentStorage存储的json字符串

如果没用持久化 。那么读取出来的对象就是AppStorage对象

只要初始化了数据,我们以后使用AppStorage就可以读取和设置,它会自动同步到我们的磁盘上

目前不支持复杂对象的持久化,如果你需要存储,你需要把它序列化成功字符串

  • 测试:需要在真机或模拟器调试

限制条件

PersistentStorage允许的类型和值有:

  • number, string, boolean, enum 等简单类型。
  • 可以被JSON.stringify()和JSON.parse()重构的对象,但是对象中的成员方法不支持持久化。
  • API 12 及以上版本支持 Date, Map, Set 等内置类型。

PersistentStorage不允许的类型和值有:

  • 不支持嵌套对象(对象数组,对象的属性是对象等)。因为目前框架无法检测 AppStorage 中嵌套对象(包括数组)值的变化,所以无法写回到 PersistentStorage 中。

持久化数据是一个相对缓慢的操作,应用程序应避免以下情况:

  • 持久化大型数据集。
  • 持久化经常变化的变量。

PersistentStorage的持久化变量最好是小于2kb的数据,不要大量的数据持久化,因为PersistentStorage写入磁盘的操作是同步的,大量的数据本地化读写会同步在UI线程中执行,影响UI渲染性能。如果开发者需要存储大量的数据,建议使用数据库api。

PersistentStorage只能在UI页面内使用,否则将无法持久化数据。

注意:要在使用AppStorage之前,UI实例初始化成功后,调用PersistentStorage进行初始化,这样才能将AppStorage中key对应的属性持久化到文件中,我是直接在加载页面的回调中调用的。

用PersistentStorage持久化存储token和用户信息的例子

import { TOKEN_KEY, USER_INFO } from '../constants'
import { UserInfoClass } from '../viewmodels'
 
// 封装存储
export class UserSetting {
  // 持久化存储
  initSetting() {
    PersistentStorage.persistProp<UserInfoClass>(USER_INFO, {}) // 用户信息
    PersistentStorage.persistProp<string>(TOKEN_KEY, '') // token
    // ... 有就在加
  }
 
  // 用户信息 -------------------------------------
  // 获取
  getSetting(): UserInfoClass{
    return AppStorage.get<UserInfoClass>(USER_INFO) as UserInfoClass
  }
  // 设置
  setSetting(user: UserInfoClass) {
    AppStorage.set<UserInfoClass>(USER_INFO, user)
  }
  // token --------------------------------------
  // 获取token
  getToken(): string {
    return AppStorage.get<string>(TOKEN_KEY) as string
  }
  // 设置token
  setToken(token: string) {
    AppStorage.set<string>(TOKEN_KEY, token)
  }
  // ------ 有就在加
}
// 导出
export const userSetting = new UserSetting()

Preferences 首选项

基本概念:

  • 创建首选项-仓库的概念- 应用可以有N个仓库,一个仓库中可以有N个key
  • 用户首选项为应用提供Key-Value键值型的数据处理能力,支持应用持久化轻量级数据,并对其修改和查询。
  • 数据存储形式为键值对,键的类型为字符串型,值的存储数据类型包括数字型、字符型、布尔型以及这3种类型的数组类型。

条件限制:

  • Key键为string类型,要求非空且长度不超过1024个字节。
  • 如果Value值为string类型,请使用UTF-8编码格式,可以为空,不为空时长度不超过16 Mb个字节。
  • 内存会随着存储数据量的增大而增大,所以存储的数据量应该是轻量级的,建议存储的数据不超过一万条,否则会在内存方面产生较大的开销。
  1. 获取首选项实例
const dataPreferences = preferences.getPreferencesSync(context, { name: '' });
  1. 写入|修改,并持久化
dataPreferences.putSync('startup', 'auto');
dataPreferences.flush()
  1. 读取
dataPreferences.getSync('startup', 默认值 )   // 获取不到的时候,用默认值
  1. 删除,并持久化
dataPreferences.deleteSync('startup');
dataPreferences.flush()
  1. 删除首选项实例
preferences.deletePreferences(context, options)


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值