3、Preferences实战:创建、读写与删除

好,咱们今天来聊聊 Preferences 的实战操作。说实话,这个 API 在鸿蒙开发里属于那种「看着简单,用着顺手」的类型。我最早接触它的时候,还觉得不就是个键值对存储嘛,能有什么花头?结果真在项目里用起来,发现坑还真不少。今天我就把创建实例、写入、读取、删除这四步,掰开了揉碎了讲清楚。

3.1 创建 Preferences 实例

先说说怎么拿到一个 Preferences 对象。在鸿蒙里,你不能直接 new 一个出来,得通过 dataPreferences 这个模块来获取。

import dataPreferences from '@ohos.data.preferences';

// 获取 Preferences 实例
let preferences = await dataPreferences.getPreferences(
    globalThis.context,
    'my_preferences'
);

这里有两个参数:第一个是上下文(context),第二个是存储文件的名称。我个人习惯把文件名起得有意义一点,比如 user_settings 或者 app_config,别用 test 这种名字——你想想看,项目大了以后,满屏的 test 文件,找起来多头疼。

小提示:getPreferences 是异步的,记得用 await 或者 .then() 处理。我见过有人忘了 await,结果后面读写数据全是 undefined,排查了半天。

3.2 写入数据(put)

拿到实例之后,写入数据就简单了。Preferences 支持多种数据类型:string、number、boolean、Array、Object 等等。

// 写入字符串
await preferences.put('username', '张三');

// 写入数字
await preferences.put('age', 25);

// 写入布尔值
await preferences.put('isVip', true);

// 写入对象(需要先转成 JSON 字符串)
let userInfo = { name: '张三', level: 5 };
await preferences.put('userInfo', JSON.stringify(userInfo));

// 别忘了 flush!不然数据可能没写进去
await preferences.flush();

嗯,这里要注意一个点:put 之后一定要调用 flush()。为什么?因为 Preferences 默认是异步写入的,你不 flush,数据可能还在内存里,没落到磁盘上。我曾经在项目里遇到过一个问题:用户修改了设置,退出应用再进来,设置居然没变。排查了半天,发现就是忘了 flush。

警告:flush 是异步操作,记得 await。另外,频繁调用 flush 会影响性能,建议在批量写入完成后统一调用一次。

3.3 读取数据(get)

读取数据同样简单,用 get 方法就行。不过要注意,读取的时候需要指定默认值——万一这个 key 不存在,程序不会崩溃,而是返回你给的默认值。

// 读取字符串
let username = await preferences.get('username', '默认用户');

// 读取数字
let age = await preferences.get('age', 0);

// 读取布尔值
let isVip = await preferences.get('isVip', false);

// 读取对象(记得反序列化)
let userInfoStr = await preferences.get('userInfo', '{}');
let userInfo = JSON.parse(userInfoStr);

我个人习惯把默认值设得「安全」一点。比如读取用户昵称,默认值给个「游客」而不是空字符串。这样 UI 层就不用额外判断了,直接显示就行。

3.4 删除数据(delete)

删除数据有两种方式:删除单个 key,或者清空整个 Preferences 文件。

// 删除单个 key
await preferences.delete('username');
await preferences.flush();

// 清空所有数据
await preferences.clear();
await preferences.flush();

这里有个坑:deleteclear 之后,同样需要 flush()。我记得有一次,我在测试环境里删了一个 key,结果发现数据还在,就是因为忘了 flush。嗯,这个坑我踩过,你们就别再踩了。

3.5 完整实战示例

下面是一个完整的例子,把创建、写入、读取、删除串起来。你可以直接复制到你的项目里跑一下。

import dataPreferences from '@ohos.data.preferences';

async function preferencesDemo() {
    // 1. 创建实例
    let preferences = await dataPreferences.getPreferences(
        globalThis.context,
        'demo_preferences'
    );

    // 2. 写入数据
    await preferences.put('name', '李四');
    await preferences.put('score', 98);
    await preferences.put('isPass', true);
    await preferences.flush();
    console.info('数据写入成功');

    // 3. 读取数据
    let name = await preferences.get('name', '未知');
    let score = await preferences.get('score', 0);
    let isPass = await preferences.get('isPass', false);
    console.info(`姓名:${name},分数:${score},是否通过:${isPass}`);

    // 4. 删除数据
    await preferences.delete('score');
    await preferences.flush();
    console.info('score 已删除');

    // 5. 验证删除
    let scoreAfterDelete = await preferences.get('score', -1);
    console.info(`删除后 score 的值:${scoreAfterDelete}`); // 输出 -1
}

3.6 知识体系图

下面这张图帮你理清 Preferences 的核心操作流程:

Preferences 核心操作流程 创建实例 getPreferences() 写入数据 put() + flush() 读取数据 get() 删除数据 delete() / clear() 注意:写入和删除操作后,必须调用 flush() 才能持久化到磁盘

3.7 避坑指南

最后,我把自己踩过的坑总结一下,你们遇到类似问题可以少走弯路。

常见问题 原因 解决方案
写入后读取不到数据 忘了调用 flush() 写入后记得 await flush()
读取对象时崩溃 没有先 JSON.stringify 再存 存对象前先转字符串,读出来再 parse
多次调用 flush 性能差 每次 put 都 flush 一次 批量写入后统一 flush
文件名冲突 多个模块用了同一个文件名 按模块命名,如 user_preferences、config_preferences

好了,Preferences 的实战操作就讲到这里。说白了就是四个步骤:创建、写入、读取、删除。你只要记住「写完要 flush,读时要默认值」,基本就不会出大问题。下次咱们聊聊更高级的用法,比如数据变更监听和批量操作。

专注资料整理