【高心星出品】
AppStorageV2和PersistenceV2的使用
概念
在HarmonyOS鸿蒙开发中,AppStorageV2和PersistenceV2是状态管理V2版本的核心工具,用于实现应用全局状态管理和持久化存储。以下是两者的关键特性和使用指南:
特性 | AppStorageV2 | PersistenceV2 |
---|---|---|
作用 | 应用全局UI状态存储(运行时内存) | UI状态持久化存储(设备磁盘) |
数据生命周期 | 应用运行期间保留 | 应用重启后仍然保留 |
数据同步 | 实时同步到内存 | 自动/手动同步到磁盘 |
典型场景 | 跨页面共享临时数据(如用户登录状态) | 需长期保存的配置(如用户偏好设置) |
AppStorageV2常用方法
AppStorageV2是在应用UI启动时会被创建的单例。它的目的是为了提供应用状态数据的中心存储,这些状态数据在应用级别都是可访问的。AppStorageV2将在应用运行过程保留其数据。数据通过唯一的键字符串值访问。需要注意的是,AppStorage与AppStorageV2之间的数据互不共享。
AppStorageV2可以修改connect的返回值,实现与UI组件的同步。
AppStorageV2只能保存class类型的数据。
AppStorageV2支持应用的主线程内多个UIAbility实例间的状态共享。
connect:创建或获取存储的数据。
remove:删除指定key的存储数据。
keys:返回所有AppStorageV2中的key。
PersistenceV2常用方法
PersistenceV2是继承自AppStorageV2,在应用UI启动时会被创建的单例。它的目的是提供应用状态数据的中心存储,这些状态数据在应用级别都是可访问的。数据通过唯一的键值字符串访问。不同于AppStorageV2,PersistenceV2还将最新数据存储在设备磁盘上(持久化)。这意味着,应用退出再次启动后,依然能保存选定的结果。
对于与PersistenceV2关联的@ObservedV2对象,该对象的@Trace属性的变化,会触发整个关联对象的自动持久化;非@Trace属性的变化则不会,如有必要,可调用PersistenceV2 API手动持久化。请注意:被PersistenceV2持久化的类属性必须要有初值,否则不支持持久化。
PersistenceV2可以和UI组件同步,且可以在应用业务逻辑中被访问。
PersistenceV2支持应用的主线程内多个UIAbility实例间的状态共享。
connect:创建或获取存储的数据。
globalConnect:创建或获取存储的数据。
remove:删除指定key的存储数据。删除PersistenceV2中不存在的key会报警告。
keys:返回所有PersistenceV2中的key。包括module级别存储路径和应用级别存储路径中的所有key。
save:手动持久化数据。
notifyOnError:响应序列化或反序列化失败的回调。将数据存入磁盘时,需要对数据进行序列化;当某个key序列化失败时,错误是不可预知的;可调用该接口捕获异常。
在HarmonyOS鸿蒙开发中,PersistenceV2
的connect
和globalConnect
接口均用于持久化数据的管理,但两者在存储路径和应用场景上有显著差异。以下是核心区别和使用建议:
特性 | connect | globalConnect |
---|---|---|
存储路径级别 | 模块(module)级别 | 应用级别 |
数据隔离性 | 不同模块使用相同key时会创建独立数据副本 | 跨模块共享同一份数据 |
适用场景 | 模块内部数据隔离存储 | 跨模块共享数据 |
API版本支持 | API version 12+ | API version 18+(需注意版本兼容性) |
数据副本风险 | 若Ability被多个模块拉起,可能产生多份 | 全局唯一副本,避免冗余 |
案例
appstoragev2数据存储案例:
包括获取数据,同步更新数据,遍历数据,移除数据等。

less
import { AppStorageV2 } from '@kit.ArkUI';
// appstorage保存的数据必须是对象
// 后面使用的过程中 每个属性一般都有默认值
@ObservedV2
class Userinfo{
@Trace name:string='gxx'
age:number=30
}
@Entry
@ComponentV2
struct Appstoragepage {
// 获取key为ui 类型为Userinfo的数据,如果appstorage中不存在则使用默认构造方法初始化的值
@Local user:Userinfo=AppStorageV2.connect<Userinfo>(Userinfo,'ui',()=>new Userinfo())!
// 获取key为 Userinfo的数据 如果appstorage中不存在则使用默认构造方法初始化的值
// @Local user:Userinfo=AppStorageV2.connect<Userinfo>(Userinfo,()=>{return new Userinfo()})!
// 获取key为Userinfo的数据 保证Appstorage中一定有该数据 否则出问题
// @Local user:Userinfo=AppStorageV2.connect<Userinfo>(Userinfo)!
@Local keys:string=''
@Local datas:string=''
build() {
Column({space:20}){
Button('保存的数据为: '+`name: ${this.user.name}`)
.width('60%')
.onClick(()=>{
// 数据更新之后 name会刷新ui 而age不会刷新,但是都会同步到appstorage中
this.user.name='ggl'
// 重新获取一下appstorage中存储的数据
this.datas=JSON.stringify(AppStorageV2.connect<Userinfo>(Userinfo,'ui',()=>new Userinfo())!)
})
Button('保存的数据为: '+`age: ${this.user.age}`)
.width('60%')
.onClick(()=>{
// 数据更新之后 name会刷新ui 而age不会刷新,但是都会同步到appstorage中
this.user.age+=1
// 重新获取一下appstorage中存储的数据
this.datas=JSON.stringify(AppStorageV2.connect<Userinfo>(Userinfo,'ui',()=>new Userinfo())!)
})
Text('当前的数据'+this.datas)
Button('所有的key')
.width('60%')
.onClick(()=>{
// 拿到所有的key
this.keys= AppStorageV2.keys().join(' ')
})
Text(this.keys)
Button('移除某个数据')
.width('60%')
.onClick(()=>{
// appstorage 移除key为ui的数据
AppStorageV2.remove('ui')
})
}
.height('100%')
.width('100%')
}
}
PersistenceV2数据持久化案例:
包括数据模块级别的持久化保存,更新和移除功能。

less
import { PersistenceV2 } from '@kit.ArkUI';
// persidencev2保存的数据必须是对象
// 后面使用的过程中 每个属性一般都有默认值
@ObservedV2
class Userinfo{
// name属性由@Trace装饰,name更新会引起自动持久化
@Trace name:string='gxx'
// age 属性不会引起自动持久化,需要手动持久化
age:number=30
}
@Entry
@ComponentV2
struct Persistencev2 {
// 获取key为ui 类型为Userinfo的数据,如果persistencev2中不存在则使用默认构造方法初始化的值
@Local user:Userinfo=PersistenceV2.connect<Userinfo>(Userinfo,'ui',()=>new Userinfo())!
// 获取key为 Userinfo的数据 如果persistencev2中不存在则使用默认构造方法初始化的值
// @Local user:Userinfo=PersistenceV2.connect<Userinfo>(Userinfo,()=>{return new Userinfo()})!
// 获取key为Userinfo的数据 保证PersistenceV2中一定有该数据 否则出问题
// @Local user:Userinfo=PersistenceV2.connect<Userinfo>(Userinfo)!
@Local keys:string=''
@Local datas:string=''
build() {
Column({space:20}){
Button('保存的数据为: '+`name: ${this.user.name}`)
.width('60%')
.onClick(()=>{
// 数据更新之后 name会刷新ui 而age不会刷新,name会同步到PersistenceV2中而age不会
this.user.name='ggl'
// 重新获取persidence中的数据
this.datas=JSON.stringify(PersistenceV2.connect<Userinfo>(Userinfo,'ui',()=>new Userinfo())!)
})
Button('保存的数据为: '+`age: ${this.user.age}`)
.width('60%')
.onClick(()=>{
// 数据更新之后 name会刷新ui 而age不会刷新,name会同步到PersistenceV2中而age不会
this.user.age+=1
// 手动保存数据
PersistenceV2.save('ui')
// 重新获取persidence中的数据
this.datas=JSON.stringify(PersistenceV2.connect<Userinfo>(Userinfo,'ui',()=>new Userinfo())!)
})
Text('当前数据为: '+this.datas)
Button('所有的key')
.width('60%')
.onClick(()=>{
// 拿到所有的key
this.keys= PersistenceV2.keys().join(' ')
})
Text(this.keys)
Button('移除某个数据')
.width('60%')
.onClick(()=>{
// PersistenceV2 移除key为ui的数据
try {
PersistenceV2.remove('ui')
} catch (err) {
console.error('Remove failed:', err.code, err.message)
}
})
}
.height('100%')
.width('100%')
}
}