PersistenceV2: 持久化储存UI状态
developer.huawei.com/consumer/cn…
PersistenceV2是在应用UI启动时会被创建的单例。它的目的是为了提供应用状态数据的中心存储,这些状态数据在应用级别都是可访问的。数据通过唯一的键字符串值访问。不同于AppStorageV2,PersistenceV2还将最新数据储存在设备磁盘上(持久化)。这意味着,应用退出再次启动后,依然能保存选定的结果
转换前
ts 代码解读复制代码/**
*
* PersistenceV2Cmp.ets
* Created by unravel on 2024/8/2
* @abstract
*/
import { router, PersistenceV2 } from '@kit.ArkUI';
import { Type } from '@kit.ArkUI';
// 数据中心
@ObservedV2
class SampleChild {
@Trace p1: number = 0;
p2: number = 10;
}
@ObservedV2
export class Sample {
// 对于复杂对象需要@Type修饰,确保序列化成功
@Type(SampleChild)
@Trace f: SampleChild = new SampleChild();
}
// 接受序列化失败的回调
PersistenceV2.notifyOnError((key: string, reason: string, msg: string) => {
console.error(`error key: ${key}, reason: ${reason}, message: ${msg}`);
});
@ComponentV2
export struct PersistenceV2Cmp {
// 在PersistenceV2中创建一个key为Sample的键值对(如果存在,则返回PersistenceV2中的数据),并且和prop关联
// 对于需要换connect对象的prop属性,需要加@Local修饰(不建议对属性换connect的对象)
@Local prop: Sample = PersistenceV2.connect(Sample, () => new Sample())!;
build() {
Column() {
Button('Go to page2')
.onClick(() => {
router.pushUrl({
url: 'pages/Page2'
})
})
Button('Page1 connect the key Sample')
.onClick(() => {
// 在PersistenceV2中创建一个key为Sample的键值对(如果存在,则返回PersistenceV2中的数据),并且和prop关联
// 不建议对prop属性换connect的对象
this.prop = PersistenceV2.connect(Sample, 'Sample', () => new Sample())!;
})
Button('Page1 remove the key Sample')
.onClick(() => {
// 从PersistenceV2中删除后,prop将不会再与key为Sample的值关联
PersistenceV2.remove(Sample);
})
Button('Page1 save the key Sample')
.onClick(() => {
// 如果处于connect状态,持久化key为Sample的键值对
PersistenceV2.save(Sample);
})
Text(`Page1 add 1 to prop.p1: ${this.prop.f.p1}`)
.fontSize(30)
.onClick(() => {
this.prop.f.p1++;
})
Text(`Page1 add 1 to prop.p2: ${this.prop.f.p2}`)
.fontSize(30)
.onClick(() => {
// 页面不刷新,但是p2的值改变了
this.prop.f.p2++;
})
// 获取当前PersistenceV2里面的所有key
Text(`all keys in PersistenceV2: ${PersistenceV2.keys()}`)
.fontSize(30)
}
}
}
转换后
ts 代码解读复制代码if (!("finalizeConstruction" in ViewPU.prototype)) {
Reflect.set(ViewPU.prototype, "finalizeConstruction", () => { });
}
import router from "@ohos:router";
import { PersistenceV2 } from "@ohos:arkui.StateManagement";
import { Type } from "@ohos:arkui.StateManagement";
// 数据中心
@ObservedV2
class SampleChild {
@Trace
p1: number = 0;
p2: number = 10;
}
@ObservedV2
export class Sample {
// 对于复杂对象需要@Type修饰,确保序列化成功
@Type(SampleChild)
@Trace
f: SampleChild = new SampleChild();
}
// 接受序列化失败的回调
PersistenceV2.notifyOnError((key: string, reason: string, msg: string) => {
console.error(`error key: ${key}, reason: ${reason}, message: ${msg}`);
});
export class PersistenceV2Cmp extends ViewV2 {
constructor(parent, params, __localStorage, elmtId = -1, paramsLambda, extraInfo) {
super(parent, elmtId, extraInfo);
this.prop = PersistenceV2.connect(Sample, () => new Sample())!;
this.finalizeConstruction();
}
// 在PersistenceV2中创建一个key为Sample的键值对(如果存在,则返回PersistenceV2中的数据),并且和prop关联
// 对于需要换connect对象的prop属性,需要加@Local修饰(不建议对属性换connect的对象)
@Local
prop: Sample;
initialRender() {
this.observeComponentCreation2((elmtId, isInitialRender) => {
Column.create();
}, Column);
this.observeComponentCreation2((elmtId, isInitialRender) => {
Button.createWithLabel('Go to page2');
Button.onClick(() => {
router.pushUrl({
url: 'pages/Page2'
});
});
}, Button);
Button.pop();
this.observeComponentCreation2((elmtId, isInitialRender) => {
Button.createWithLabel('Page1 connect the key Sample');
Button.onClick(() => {
// 在PersistenceV2中创建一个key为Sample的键值对(如果存在,则返回PersistenceV2中的数据),并且和prop关联
// 不建议对prop属性换connect的对象
this.prop = PersistenceV2.connect(Sample, 'Sample', () => new Sample())!;
});
}, Button);
Button.pop();
this.observeComponentCreation2((elmtId, isInitialRender) => {
Button.createWithLabel('Page1 remove the key Sample');
Button.onClick(() => {
// 从PersistenceV2中删除后,prop将不会再与key为Sample的值关联
PersistenceV2.remove(Sample);
});
}, Button);
Button.pop();
this.observeComponentCreation2((elmtId, isInitialRender) => {
Button.createWithLabel('Page1 save the key Sample');
Button.onClick(() => {
// 如果处于connect状态,持久化key为Sample的键值对
PersistenceV2.save(Sample);
});
}, Button);
Button.pop();
this.observeComponentCreation2((elmtId, isInitialRender) => {
Text.create(`Page1 add 1 to prop.p1: ${this.prop.f.p1}`);
Text.fontSize(30);
Text.onClick(() => {
this.prop.f.p1++;
});
}, Text);
Text.pop();
this.observeComponentCreation2((elmtId, isInitialRender) => {
Text.create(`Page1 add 1 to prop.p2: ${this.prop.f.p2}`);
Text.fontSize(30);
Text.onClick(() => {
// 页面不刷新,但是p2的值改变了
this.prop.f.p2++;
});
}, Text);
Text.pop();
this.observeComponentCreation2((elmtId, isInitialRender) => {
// 获取当前PersistenceV2里面的所有key
Text.create(`all keys in PersistenceV2: ${PersistenceV2.keys()}`);
// 获取当前PersistenceV2里面的所有key
Text.fontSize(30);
}, Text);
// 获取当前PersistenceV2里面的所有key
Text.pop();
Column.pop();
}
rerender() {
this.updateDirtyElements();
}
}
AppStorageV2 类
底层的实际处理类是PersistenceV2Impl
PersistenceV2.persistenceV2Impl_ = PersistenceV2Impl.instance();
class PersistenceV2Impl extends StorageHelper
public connect(type: TypeConstructorWithArgs, keyOrDefaultCreator?: string | StorageDefaultCreator, defaultCreator?: StorageDefaultCreator): T | undefined
PersistenceV2和AppStorageV2一样
对于内存缓存,存储的是一个对象的引用,然后App内多个页面之所以能够同步是因为他们访问的是同一个对象
对于磁盘缓存,存储的是序列化的json字符串
PersistenceV2本身不能观察数据的变化,实际驱动UI刷新的动作还需要数据自身来完成,即对应的class必须使用ObservedV2和Trace装饰
评论记录:
回复评论: