鸿蒙开发基础 - 首选项持久化数据使用及封装

1,654 阅读5分钟

1. 什么是数据持久化?数据持久化有什么用?

在日常的开发中,我们可能遇到需要持久的记录某些数据。确保在应用被关闭后,数据依然可以保存下来,而不是每次打开都被初始化
那么,什么是数据持久化呢?简单的来讲,就是把数据保存到磁盘空间,而非是内存中(内存中的数据会在进程销毁后丢失)。
数据持久化有什么用呢?打开比方,我们开发了一个小说阅读的软件。在设置中用户可以设置阅读时的字体颜色,大小,粗细,行高等属性。当用户设置完后,可以用数据持久化来保存这些参数,避免了用户每次打开应用都要重新设置这些一遍参数

cac7e721e12eeac6f20714cd30377876.jpeg

2. 在鸿蒙开发中,如何使用数据持久化?

其实鸿蒙开发中,给我们提供了非常多的数据持久化方案。这里简单列举几个:

  • 应用级变量的状态管理:PersistentStorage
  • 用户首选项:preferences
  • fs文件操作模块
  • 轻量级关系型数据库(RDB):relationalstore
  • ...

在这里,主要介绍用户首选项 preferences 来做数据持久化

2e59fed0ba3d555346793840ec38671a.jpeg

首先,让我们来看看官网对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';

bbb6fc1ef79bebe7429980c1cf3bddf6.jpeg

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,打开文件目录窗口

image.png

这里的路径为:/data/app/el2/100/base/com.example.myharmony/haps/entry/preferences image.png

如果preferences文件夹内没有文件,可以同步刷新一下

image.png

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")