HarmonyOS-ArkUI V2状态-PersistenceV2:持久化存储UI状态_鸿蒙 persistencev2 数据量太大
PersistenceV2类是一个与AppStorageV2类用法非常相似的类。因为它俩是子类和父类的关系。如果不了解AppStorageV2,可以先跳转至了解一下这个类。
HarmonyOS-ArkUI V2工具类:AppStorageV2:应用全局UI状态存储-CSDN博客
PersistenceV2相比于其父类AppStorageV2而言,它存储的数据是持久化存储的。也就是它里面的数据能写在盘里,SD卡里。其周期越过了App的生命周期。本次App存储的数据,杀掉进程后, 在下次App开启的时候是可以拿到这些值的。
PersistenceV2最值得一提的作用是
- 它绑定的那些数据,持久化是自动发生的。也就是我们不用自己专门调用它也能自己持久化。但前提是您的对象要是@Trace修饰的,也就是先让此元素是具备被深度监测能力,这样PersistenceV2才能知道哪些元素发生了变化,择机持久化数据。
PersistenceV2 API
connect函数
函数声明为:
static connect( type: TypeConstructorWithArgs, keyOrDefaultCreator?: string | StorageDefaultCreator, defaultCreator?: StorageDefaultCreator ): T | undefined;
参数详解
参数名称
参数含义
type
指定的类型, 如果没有指定key,系统则会将此指定的类型作为key。
比如一个类叫 Student, 则type为 Student
keyOrDefaultCreator
指定的key, 或者默认的数据构造器
defaultCreator
默认数据的构造器
返回值
创建数据或者获取数据成功时,会返回数据。如果失败就返回undefined。
使用方式:
// Sample.etsimport { Type } from \"@kit.ArkUI\"@ObservedV2class SampleChild{ @Trace p1:number = 0 p2: number = 10}@ObservedV2export class Sample{ //注意:Type装饰器是用来表明此复杂对象的序列化类型. @Type(SampleChild) @Trace f:SampleChild = new SampleChild()}//PersistenceV2TestPage1.ets@Entry@ComponentV2struct PersistenceV2TestPage1 { @Local prop:Sample = PersistenceV2.connect(Sample, ()=> new Sample())! pathStack: NavPathStack = new NavPathStack() build() { ... }}
- 同一个key,connect不同类型的数据会导致应用异常,所以应该确保类型的匹配。
- key, 建议使用有意义的值,可以由字母,数字,下划线组成,长度不得超过255,使用非法字符或者靠字符的行为是未定义的。
remove 删除指定的key的存储数据
这个函数只有一个参数,指的是需要删除的key, 如果指定的是type类型,删除的key为type的name。
static remove(keyOrType: string | TypeConstructorWithArgs): void;
注意: 如果您删除了PersistenceV2中不存在的key,会触发警告。
keys:返回所有PersistenceV2中的key
这个在下述代码中有书写。使用方式参考代码。
save: 手动持久化数据
手动触发持久化数据。但是注意一下,只有数据处于connect状态,这个函数才能真正执行话。
static save(keyOrType: string | TypeConstructorWithArgs): void;
notifyOnError:响应序列化或反序列化失败的回调
将数据存入磁盘的时候,需要对数据进行序列化,当某个key序列化失败时,错误是不可预知的,可调用该接口捕获异常。
static notifyOnError(callback: PersistenceErrorCallback | undefined): void;
示例代码
PersistenceV2.notifyOnError((key: string, reason: string, message: string)=>{ console.error(`PersistenceV2 notifyOnError key=${key}, reason=${reason}, message=${message}`)})
使用案例
import { Type } from \"@kit.ArkUI\"@ObservedV2class SampleChild{ @Trace p1:number = 0 p2: number = 10}@ObservedV2export class Sample{ //Type装饰器是用来表明此复杂对象的序列化类型. @Type(SampleChild) @Trace f:SampleChild = new SampleChild()}
import { PersistenceV2 } from \'@kit.ArkUI\';import { Sample } from \'../model/Sample\';// 在全局注册的,Page之外.PersistenceV2.notifyOnError((key: string, reason: string, message: string)=>{ console.error(`PersistenceV2 notifyOnError key=${key}, reason=${reason}, message=${message}`)})@Entry@ComponentV2struct PersistenceV2TestPage1 { @Local prop:Sample = PersistenceV2.connect(Sample, ()=> new Sample())! pathStack: NavPathStack = new NavPathStack() build() { Navigation(this.pathStack) { Column(){ Button(\"点击跳转Page3\") .onClick(()=>{ this.pathStack.pushPathByName(\'Page3\', null) }) Button(\"🔗Sample对象\") //omg! emoji竟然支持! .onClick(()=>{ this.prop = PersistenceV2.connect(Sample, \'Sample\', ()=> new Sample())! }) Button(\"删掉Sample对象\") .onClick(()=>{ PersistenceV2.remove(Sample) }) Button(\"主动持久化对象\") .onClick(()=>{ // 如果处于connect状态, 持久化key为Sample的键值对 PersistenceV2.save(Sample) }) Text(`p1 自加1: ${this.prop.f.p1}`) .fontSize(30) .onClick(() => { this.prop.f.p1++; }) Text(`p2 自加1: ${this.prop.f.p2}`) .fontSize(30) .onClick(() => { // 页面不刷新,但是p2的值改变了 this.prop.f.p2++; }) // 获取当前PersistenceV2里面的所有key Text(`all keys in PersistenceV2: ${PersistenceV2.keys()}`) .fontSize(30) } .height(\'100%\') .width(\'100%\') } }}
import { Sample } from \"../model/Sample\"import { PersistenceV2 } from \"@kit.ArkUI\"@Builderexport function Page3Builder(){ PersistenceV2TestPage2()}@ComponentV2struct PersistenceV2TestPage2{ @Local prop: Sample = PersistenceV2.connect(Sample, ()=> new Sample())! build() { NavDestination(){ Column(){ Button(\"🔗Sample2\") .onClick(()=>{ this.prop = PersistenceV2.connect(Sample, \"Sample1\", ()=> new Sample())! }) Text(`p1自增1: ${this.prop.f.p1}`) .fontSize(30) .onClick(() => { this.prop.f.p1++; }) Text(`p2自增1: ${this.prop.f.p2}`) //P2 是不奏效的,因为它没有被Trace修饰,界面也不会更新,数据也不会更新 .fontSize(30) .onClick(() => { // 页面不刷新,但是p2的值改变了;只有重新初始化才会改变 this.prop.f.p2++; }) // 获取当前PersistenceV2里面的所有key Text(`所有key: ${PersistenceV2.keys()}`) .fontSize(30) } } }}
使用限制
- 需要配合UI线程使用,不能在子线程里使用,如不支持@Sendable
- 不支持Set,Map等类型
- 持久化的对象是class对象。 不支持非buildin类型,如PixelMap,NativePointer,ArrayList等Native类型。
- 单个key支持的数据为8k,太大会导致持久化失败。
- 不宜大量的持久化数据,可能会导致页面卡顿。
- 不支持循环引用的对象。//完犊子,如果是链表结构那。。。
- 只有Trace的数据改变会触发自动持久化。其余的,还有那V1版本修饰的,不支持。