1. 什么是数据持久化?数据持久化有什么用?
在日常的开发中,我们可能遇到需要持久的记录某些数据。确保在应用被关闭后,数据依然可以保存下来,而不是每次打开都被初始化
那么,什么是数据持久化呢?简单的来讲,就是把数据保存到磁盘空间,而非是内存中(内存中的数据会在进程销毁后丢失)。
数据持久化有什么用呢?打开比方,我们开发了一个小说阅读的软件。在设置中用户可以设置阅读时的字体颜色,大小,粗细,行高等属性。当用户设置完后,可以用数据持久化来保存这些参数,避免了用户每次打开应用都要重新设置这些一遍参数
2. 在鸿蒙开发中,如何使用数据持久化?
其实鸿蒙开发中,给我们提供了非常多的数据持久化方案。这里简单列举几个:
- 应用级变量的状态管理:
PersistentStorage
- 用户首选项:
preferences
fs
文件操作模块- 轻量级关系型数据库(RDB):
relationalstore
- ...
在这里,主要介绍用户首选项 preferences
来做数据持久化
首先,让我们来看看官网对preferences
的介绍:
用户首选项为应用提供Key-Value键值型的数据处理能力,支持应用持久化轻量级数据,并对其修改和查询。
数据存储形式为键值对,键的类型为字符串型,值的存储数据类型包括数字型、字符型、布尔型以及这3种类型的数组类型。
2.1 在使用前,需要我们进行导包
注意,这里可以从两个路径导入preferences
。这两个没有区别,都能用,但是更推荐从@kit.ArkData
进行导入,因为@kit.ArkData
比@ohos.data.preferences
新,@ohos.data.preferences
后续版本可能会废弃
import { preferences } from '@kit.ArkData'
import preferences from '@ohos.data.preferences';
2.2 实例化首选项
使用preferences.getPreferencesSync(context: Context, options: Options): Preferences
以同步的方法来拿到首选项的实例
这里需要两个实参,一个是上下文对象,也就是getContext()
,第二个参数是一个对象,对象内需要一个name
(key)属性,且值只能为string
类型。name
可以自行命名
注意:这个name
是首选项数据写入磁盘后文件的名字,后面也会根据这个name
去读取文件里面保存的数据
const pre = preferences.getPreferencesSync(getContext(), { name: "name" })
2.3 使用增/改、删、查三个方法
在我们拿到的pre对象上有一系列方法,具体可以查阅 官方文档
这里主要使用到4个方法来实现数据的增/改、查、删操作,分别是putSync
(增/改的同步方法),getSync
(查的同步方法),deleteSync
(删的同步方法),flush
(写入磁盘的方法,此异步操作)
注意:preferences
只支持写入最大8kb的数据,超过8kb的数据会导致写入失败!!!
pre.flush()是把结果写入磁盘的方法,为异步操作。在操作完数据之后,把结果写入磁盘,才能完成数据的持久化!!!
下面展示这三个方法的用法:
pre.putSync(key, value)
// 把内存中的数据写入磁盘,完成持久化
pre.flush()
pre.getSync(key, defaultvalue)
pre.deleteSync(key)
// 删除key对应的值,并且把结果写入磁盘
pre.flush()
key:需要保存数据的键名
value:需要保存数据的值。有类型限制,只支持保存number | string | boolean | Array<number> | Array<string> | Array<boolean> | Uint8Array
如果需要保存复杂类型(对象等),需要使用JSON.stringify()
方法转化为JSON字符串
defaultvalue:默认的返回值,如果值为null或者非默认值类型,返回默认数据defaultvalue。同样有类型限制,参考value
2.4 如何才看首选项数据有没有被写入磁盘
当我们对数据完成操作之后,对数据是否被持久化可能存在疑问。其实我们可以进入应用的文件目录来查看保存的文件数据
当我们保存完数据(使用手机模拟器)之后,在 Dev Eco Studio 中找到 Device File Browser,打开文件目录窗口
这里的路径为:/data/app/el2/100/base/com.example.myharmony/haps/entry/preferences
如果preferences
文件夹内没有文件,可以同步刷新一下
3. 对于首选项持久化的类封装
因为首选项的持久化的操作步骤过于繁琐,且时常会用到.所以毫无疑问,把这些代码封装成一个工具类可以更方便我们的使用
这里直接提供封装好的首选项持久化类,可以在各个不同的项目中通用:
import { preferences } from '@kit.ArkData'
// import preferences from '@ohos.data.preferences'
class PreferencesManager {
// 需要保存到磁盘的文件名称
private pname: string
constructor(pname: string) {
this.pname = pname
}
// 泛型继承, 规定传入的数据类型. 保存数据方法, 负责保存数据到首选项
// 规定类型为 number | string | boolean | Array<number> | Array<string> | Array<boolean> | Uint8Array;
async saveData<T extends preferences.ValueType>(key: string, value: T) {
const pre = preferences.getPreferencesSync(getContext(), { name: this.pname })
pre.putSync(key, value)
// 把内存中的数据写入磁盘,完成持久化
await pre.flush()
}
// 获取数据
// 注意, 此处使用读取数据的同步方法, 没有使用flush写入磁盘, 所以不需要加async, 加上async后会导致方法异步执行
getData<T extends preferences.ValueType>(key: string, defaultvalue: T) {
const pre = preferences.getPreferencesSync(getContext(), { name: this.pname })
return pre.getSync(key, defaultvalue) as T
}
// 删除数据
async delAllData(key: string) {
const pre = preferences.getPreferencesSync(getContext(), { name: this.pname })
pre.deleteSync(key)
await pre.flush()
}
}
// 实例化后导出, MyPreferences和Store可自行按需求命名
export const MyPreferences = new PreferencesManager("Store")