接下来 我们来说说数据持久化的问题
我们平时处理的数据都是在内存中处理的
我们应用一点重启 所有数据都消失了 肯恩是不符合一些场景的
harmonyos中 提供了比较多的解决方案
最多的两种是
用户首选项
关系型数据库
本文的话 我们就来看看 用户首选项
首先,什么是用户首选项?
全称 Preference 它为应用提供了 key-value 键值对形式的数据处理,支持应用轻量级的持久化数据
轻量级 就是指 比如 name 啊 age呀 这种 一个字符串 一个数字 或者 布尔 这种 占内存非常小的数据类型
首选项 就能为它们提供持久化处理
这里 有几个注意事项
key 必须是字符串类型 且长度不能超过 88 个字符
value 类型可以是 string number boolean 或者这些类型的数组,数据总大小不能超过 8192 字节
数据量 建议不超过一万条
毕竟说是轻量级
那么 话不多说 我们直接来看用法
首先 建议不要直接写在代码中 我们将首选项的代码逻辑 抽离出来 看着会更规范 也更好解决一点
我们在对应模块 下的 ets目录下 创建一个包 我这里叫 utils
下面创建一个 TS文件
我这里 先叫 PreferencesUtil
编写代码如下
//导入 preferences 首选项操作对象 这个包是harmonyos自带的 无需安装
import preferences from '@ohos.data.preferences';
//创建类对象 名称叫 PreferencesUtil
class PreferencesUtil{
//定义一个map 存储所有进入 首选项的键值
prefMap: Map<string,preferences.Preferences> = new Map()
//加载实例
async getPreferences(context,name:string){
try {
/*
* preferences.getPreferences用于获取首选项实例方法 读取指定文件
* 参数context 是UIAbility的 上下文 UIAbilityContext
* name 字符串 首选项名称 用于区分 不能重名
*/
let pref = await preferences.getPreferences(context, name);
//将当前初始化的实力的 name 和实例对象 存入 prefMap 集合对象
this.prefMap.set(name, pref);
//在控制台 输出成功结果
console.log('testTag',`加载Preferences[${name}]成功`)
}catch(e) {
//在控制台 输出失败结果 将失败信息对象 转成 字符串类型stringify
console.log('testTag',`加载Preferences[${name}]失败`,JSON.stringify(e))
}
}
/*
* put数据进首选项 首选项的put函数 如果对应key 有值就是替换 没值就是赋值
* name 要存入哪一个首选项 name名称寻找
* key 键值对 键
* value 要存入的值preferences.ValueType 类型就是 string boolean number
*/
async putPreferenceValue(name: string, key: string, value: preferences.ValueType){
//判断 名称能否在 prefMap集合中找到
if(!this.prefMap.has(name)){
//如果找不到对应名称 说明 没有对应name 的首选项 那么 直接抛回去
console.log('testTag',`Preferences[${name}]尚未初始化!`)
return
}
//如果name 在首选项中是存在的 通过 this.prefMap.get(name) 获取到存入的首选项对象
let pref = this.prefMap.get(name);
// 然后调用它的 put 将键值对存进去
await pref.put(key,value);
//对象刷盘
await pref.flush()
console.log('testTag',`保存Preferences[${name}.${key} = ${value}]成功`)
}
/*
* 通过name名称与key键 defaultValue默认值
* get获取指定首选项中指定key的值
*/
async getPreferenceValue(name: string, key: string, defaultValue: preferences.ValueType){
//判断 名称能否在 prefMap集合中找到
if(!this.prefMap.has(name)){
//如果找不到对应名称 说明 没有对应name 的首选项 那么 直接抛回去
console.log('testTag',`Preferences[${name}]尚未初始化!`)
return
}
//如果name 在首选项中是存在的 通过 this.prefMap.get(name) 获取到存入的首选项对象
let pref = this.prefMap.get(name);
/*
* 调用 首选项实例的 get 函数 传入 key与默认值 就是我们传入的 defaultValue
* 然后get就会返回 首选项中存的真正的值 然后我们直接将结果return回去
*/
return await pref.get(key,defaultValue);
}
deleteference(name: string, key: string) {
//判断 名称能否在 prefMap集合中找到
if(!this.prefMap.has(name)){
//如果找不到对应名称 说明 没有对应name 的首选项 那么 直接抛回去
console.log('testTag',`Preferences[${name}]尚未初始化!`)
return
}
//如果name 在首选项中是存在的 通过 this.prefMap.get(name) 获取到存入的首选项对象
let pref = this.prefMap.get(name);
try {
//通过首选项实例调用delete 删除指定key
pref.delete(key)
}catch(e) {
//操作失败 输出原因
console.log('testTag',`Preferences[${name}.${key}]删除失败`,JSON.stringify(e))
}
}
}
//new 一个PreferencesUtil类的实力对象
const preferencesUtil = new PreferencesUtil()
//将实力对象导出
export default preferencesUtil as PreferencesUtil
我感觉自己注释已经写的超级认真了
反正就是 一开始 要preferences.getPreferences 初始化 对应name 的首选项实例
然后 通过实例 可以put 加入 键值
get 获取值
delete 删除键值对
然后 我们在模块入口的 onCreate 生命周期中 去写这个初始化的逻辑
这里 我们导入 自己写的 PreferencesUtil
然后调用它的 getPreferences
第一个参数 是 Ability 上下文中 AbilityContext
第二个参数 是首选项的name 名称
如果有多个 就可以 执行多次 创建不同name的
如下图 因为是异步的 所以 要用 async和await 处理成同步的
我们 index 首页 可以这样写
import PreferencesUtil from "../utils/PreferencesUtil"
@Entry
@Component
struct Dom {
@State fontSize:number = 0;
async aboutToAppear(){
await PreferencesUtil.putPreferenceValue("grKey","name",112)
this.fontSize = await PreferencesUtil.getPreferenceValue("grKey","name",12) as number;
}
build() {
Column({space: 30}) {
Text("getPreferenceValue值为"+this.fontSize)
}
.width('100%')
.height('100%')
}
}
先 put 加数据 然后 get 获取这个数据
然后用 Text 组件 输出它的值 看看有没有问题
我们 真机运行 这个值就出来了