别再用数据库存小数据了!HarmonyOS Preferences轻量存储看完就会
引言
你的App里是不是经常要存这些东西:主题暗色/亮色、字体大小、自动保存开关、上次登录时间……
数据量小、读写频繁、不值得开数据库——那就对了,这就是 HarmonyOS @ohos.data.preferences 的战场。
Preferences 是鸿蒙内置的轻量级键值对存储方案,属于 @kit.ArkData。一句话总结它的API设计:异步获取实例,同步操作数据。支持 9 种数据类型,数据自动持久化为沙箱内 XML 文件,卸载即清除,零权限。
本文带你从零上手 Preferences,并在文末构建一个完整的"首选项实验室"Demo。
一、核心API一览
import preferences from '@ohos.data.preferences';
获取实例是唯一的异步操作:
const ctx = getContext(this);
preferences.getPreferences(ctx, 'my_config').then((prefs) => {
// 之后全是同步操作
prefs.putSync('theme', 'dark');
prefs.flushSync();
});
拿到实例后,你只需要记住这6个方法:
| 方法 | 说明 |
|---|---|
putSync(key, value) |
写入键值对 |
getSync(key, defValue) |
读取值(不存在返回默认值) |
hasSync(key) |
检查键是否存在 |
deleteSync(key) |
删除指定键 |
flushSync() |
强制写入磁盘 |
on/off('change', cb) |
注册/移除变更监听 |
设计哲学:getPreferences 需要从磁盘加载XML文件,所以是异步的。但加载完成后所有操作都在内存中进行,所以设计为同步方法——既保证了UI不被阻塞,又让代码写起来简单直接。
二、ValueType:9种数据类型随便存
type ValueType = number | string | boolean | Array<number> | Array<string> |
Array<boolean> | Uint8Array | object | bigint;
看几个实际例子:
prefs.putSync('username', 'Alice'); // 字符串
prefs.putSync('fontSize', 16); // 数字
prefs.putSync('autoSave', true); // 布尔
prefs.putSync('userProfile', { // 对象(自动序列化)
name: 'Alice', age: 25, vip: true
});
prefs.putSync('maxId', BigInt(999999)); // bigint
prefs.putSync('avatar', new Uint8Array( // 二进制
[0x89, 0x50, 0x4E, 0x47]
));
两个硬性限制要记住:
- MAX_KEY_LENGTH = 80:键名最长80字符
- MAX_VALUE_LENGTH = 8192:字符串值最长8192字符
超过限制就用 @ohos.file.fs 文件存储,别硬塞 Preferences。
三、flushSync:数据落盘的关键一步
关键点:不调 flushSync(),数据只在内存里。App崩溃或被系统杀死,数据就丢了。
prefs.putSync('theme', 'dark');
prefs.putSync('fontSize', 14);
prefs.flushSync(); // 此时才真正写磁盘
文件存在沙箱里,路径是 /data/storage/el2/base/preferences/,直接用文本编辑器就能打开看:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<preferences>
<string name="username">Alice</string>
<int name="fontSize" value="16"/>
<boolean name="autoSave" value="true"/>
</preferences>
可读、可手动修复、可调试——这是 Preferences 相比数据库的一大优势。
四、变更监听:on/off(‘change’)
// 注册监听
prefs.on('change', (data: { key: string }) => {
console.log('键值已变更: ' + data.key);
});
// 移除监听
prefs.off('change');
最常用的两个场景:
- 跨页面配置同步:页面A改了主题,页面B通过 change 事件立即感知
- 调试审计:开发阶段追踪所有配置变更
注意:组件销毁时一定要 off('change'),否则内存泄漏。
五、实战:首选项存储实验室
下面构建一个完整Demo,在页面上完成键值对的写入、读取、删除和实时监听。
5.1 状态模型设计
@State prefsReady: boolean = false; // Preferences是否已加载
@State writeKey: string = 'username';
@State writeValue: string = 'Alice';
@State writeType: string = 'string'; // string/number/boolean
@State readKey: string = '';
@State readResult: string = '--';
@State kvList: KvEntry[] = []; // 已存储的键值列表
@State listenOn: boolean = false;
@State logs: LogEntry[] = [];
private prefs: preferences.Preferences | null = null;
5.2 异步加载 + 同步操作
aboutToAppear(): void {
const ctx = getContext(this);
preferences.getPreferences(ctx, 'lab_prefs').then((p) => {
this.prefs = p;
this.prefsReady = true;
this.loadAllKeys();
}).catch((e) => {
console.error('加载失败: ' + e.message);
});
}
5.3 写入带类型选择
private saveValue(): void {
if (!this.prefs) return;
let value: preferences.ValueType;
switch (this.writeType) {
case 'number':
value = parseFloat(this.writeValue);
if (isNaN(value)) return;
break;
case 'boolean':
value = this.writeValue.toLowerCase() === 'true';
break;
default:
value = this.writeValue;
}
this.prefs.putSync(this.writeKey.trim(), value);
this.prefs.flushSync();
this.loadAllKeys();
}
5.4 扫描已存储键值
private loadAllKeys(): void {
if (!this.prefs) return;
this.kvList = [];
const testKeys = ['username', 'theme', 'fontSize', 'autoSave', 'lastLogin'];
for (const key of testKeys) {
const val = this.prefs.getSync(key, '');
if (val !== '' && val !== undefined && val !== null) {
this.kvList.push({ key, value: val.toString(), vtype: typeof val });
}
}
}
5.5 变更监听开关
private toggleListener(): void {
if (!this.prefs) return;
if (this.listenOn) {
this.prefs.off('change');
this.listenOn = false;
} else {
this.prefs.on('change', () => {
this.loadAllKeys();
});
this.listenOn = true;
}
}
5.6 组件销毁清理
aboutToDisappear(): void {
if (this.listenOn && this.prefs) {
this.prefs.off('change');
}
}
六、最佳实践清单
✅ 什么时候用 Preferences
- 用户配置:主题、字体大小、开关设置
- 应用状态:首次启动标记、上次选择Tab
- 轻量缓存:最近搜索关键词、布局偏好
❌ 什么时候别用
- 数据量 > 100 个键值对 → 用
@ohos.data.relationalStore - 单值 > 8KB → 用
@ohos.file.fs - 复杂查询 → 用数据库
- 密码/Token → 用
@ohos.security.huks
⚠️ 异常处理
所有同步操作都要 try/catch 保护:
try {
prefs.putSync(key, value);
prefs.flushSync();
} catch (e) {
console.error('写入失败: ' + (e as Error).message);
}
总结
@ohos.data.preferences 是鸿蒙数据存储体系中的"轻骑兵"——与 @ohos.data.relationalStore(关系数据库)、@ohos.data.distributedKVStore(分布式KV)、@ohos.file.fs(文件存储)形成完整的数据能力栈。它是应用设置和用户偏好的第一选择:简单、可靠、零权限、开箱即用。
更多推荐



所有评论(0)