> 技术文档 > HarmonyOS-ArkUI V2状态-PersistenceV2:持久化存储UI状态_鸿蒙 persistencev2 数据量太大

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版本修饰的,不支持。