引言
本文章基于HarmonyOS NEXT操作系统,API12以上的版本。
在 ArkTS (ArkUI 框架) 中,用户首选项 (Preferences) 和 持久化存储 (PersistentStorage) 都用于数据存储,但它们有不同的应用场景和特点。
1. 用户首选项 (Preferences)
概念:
- 轻量级键值对存储,主要用于存储用户设置或小型数据,如应用配置、主题模式、语言等。
- 适用于 频繁读取 和 少量更新 的数据存储。
特点:
- 主要用于存储简单的键值对,如
boolean
、string
、number
等。 - 数据存储在 本地沙盒 中,并会在 应用重新启动后保持不变。
- 适合存储 小量数据,如 UI 设置、开关状态等。
使用场景:
- 主题模式(浅色/深色模式)。
- 语言偏好设置(中文/英文)。
- 记住用户是否已登录(布尔值)。
- 开关设置,如通知开关。
示例代码:
import preferences from '@ohos.data.preferences';// 获取 Preferences 实例
async function saveThemePreference(isDarkMode: boolean) {const preferencesInstance = await preferences.getPreferences(globalThis, 'user_settings');await preferencesInstance.put('dark_mode', isDarkMode);await preferencesInstance.flush(); // 确保数据写入
}// 读取 Preferences
async function getThemePreference(): Promise<boolean> {const preferencesInstance = await preferences.getPreferences(globalThis, 'user_settings');return await preferencesInstance.get('dark_mode', false); // 默认值 false
}
2. 核心API介绍
Preferences
组件主要提供 读取、写入、删除 用户首选项的方法。常用的 API 主要包括:
(1)获取 Preferences 实例
在 OpenHarmony 设备上,用户首选项存储在 文件 中,因此需要指定存储路径。
import preferences from '@ohos.data.preferences';async function getPreferences() {try {const pref = await preferences.getPreferences(globalThis.getContext(), 'settings.preferences');return pref;} catch (err) {console.error('获取 Preferences 失败:', err);}
}
getPreferences(context, fileName)
: 通过 文件名 获取Preferences
实例,该文件存储在应用的数据目录下。context
: 需要传入全局应用上下文globalThis.getContext()
。
(2)存储数据
使用 put()
方法存储键值对数据,并使用 flush()
进行同步保存。
async function savePreferences() {const pref = await getPreferences();if (!pref) return;pref.put('theme', 'dark'); // 存储字符串pref.put('volume', 50); // 存储数值pref.put('notifications', true); // 存储布尔值await pref.flush(); // 立即保存到本地console.log('数据已保存');
}
put(key, value)
: 存储key-value
键值对。flush()
: 同步 写入存储,否则数据可能不会立即写入。
(3)读取数据
使用 get()
方法获取存储的数据:
async function loadPreferences() {const pref = await getPreferences();if (!pref) return;const theme = pref.get('theme', 'light'); // 默认值 "light"const volume = pref.get('volume', 10); // 默认值 10const notifications = pref.get('notifications', false); // 默认值 falseconsole.log(`当前主题: ${theme}, 音量: ${volume}, 通知开关: ${notifications}`);
}
get(key, defaultValue)
: 读取 存储的值,如果键不存在,则返回默认值。
(4)删除数据
使用 delete()
方法移除指定键:
async function removePreferenceKey() {const pref = await getPreferences();if (!pref) return;pref.delete('theme'); // 删除 "theme" 配置项await pref.flush(); // 确保数据同步更新console.log('主题设置已删除');
}
delete(key)
: 删除指定key
对应的值。
(5)清除所有数据
可以使用 clear()
方法清空整个 Preferences。
async function clearPreferences() {const pref = await getPreferences();if (!pref) return;pref.clear(); // 清空所有数据await pref.flush();console.log('所有用户设置已清除');
}
clear()
: 清空所有存储的键值对数据。
3. 持久化存储 (PersistentStorage)
概念:
- 更通用的数据存储方式,可以用于存储更大规模的结构化数据,如对象、列表或复杂数据。
- 通常与本地数据库(如 SQLite 或 文件存储)结合使用。
特点:
- 适用于 存储较大数据量,如缓存数据、用户数据、应用状态等。
- 提供更丰富的 API,支持复杂的数据管理。
- 数据存储在应用的私有目录,可以长期存储,即使应用重启也不会丢失。
使用场景:
- 用户账户信息(如用户名、头像)。
- 应用的缓存数据(如搜索历史、下载列表)。
- 复杂的设置数据(如 JSON 结构的配置)。
- 离线数据存储(如离线文档、任务列表)。
示例代码(基于数据存储组件):
import { PersistentStorage } from '@ohos.data.storage';// 保存数据
async function saveUserData(userData: any) {const storage = new PersistentStorage('user_data'); // 创建存储实例await storage.set('profile', JSON.stringify(userData));await storage.flush(); // 确保数据写入
}// 读取数据
async function getUserData(): Promise<any> {const storage = new PersistentStorage('user_data');const userDataStr = await storage.get('profile', '{}'); // 默认值为空对象return JSON.parse(userDataStr);
}
4. 核心API介绍
(1)存储数据
使用 set()
方法存储数据:
storage.set('username', 'Alice');
storage.set('age', 25);
storage.set('isPremiumUser', true);
- 该方法支持存储 字符串、数值、布尔值等基本数据类型。
- 数据存储在应用本地,不会在应用重启时丢失。
(2)获取数据
使用 get<T>()
方法获取存储的数据:
let username: string = storage.get<string>('username', 'defaultUser');
let age: number = storage.get<number>('age', 0);
let isPremium: boolean = storage.get<boolean>('isPremiumUser', false);
- 参数:
- 第一个参数是键(key)。
- 第二个参数是 默认值(当 key 不存在时返回此值)。
- 返回值类型 需要显式指定(泛型
<T>
)。
(3)删除数据
使用 delete()
方法删除某个键值:
storage.delete('username');
- 删除后,使用
get()
方法查询时将返回默认值。
(4)清空所有数据
使用 clear()
方法删除所有存储的键值对:
storage.clear();
- 该方法会清除
PersistentStorage
中存储的所有数据,谨慎使用!
(5)数据是否存在
使用 has()
方法检查某个键是否存在:
if (storage.has('username')) {console.log('用户名已存储');
} else {console.log('用户名不存在');
}
(6)简单封装
以下是一个简单封装的 PersistentStorage
工具类:
import { PersistentStorage } from '@ohos.data.preferences';class StorageUtil {private static instance: PersistentStorage;private constructor() {}/*** 获取 PersistentStorage 实例(单例模式)*/private static getInstance(): PersistentStorage {if (!this.instance) {this.instance = PersistentStorage.getSharedInstance();}return this.instance;}/*** 存储数据* @param key 键名* @param value 要存储的值(支持 string、number、boolean)*/static set<T>(key: string, value: T): void {this.getInstance().set(key, value);}/*** 获取存储数据* @param key 键名* @param defaultValue 默认值(如果 key 不存在,则返回此值)* @returns 存储的数据*/static get<T>(key: string, defaultValue: T): T {return this.getInstance().get<T>(key, defaultValue);}/*** 删除指定 key 的存储数据* @param key 键名*/static delete(key: string): void {this.getInstance().delete(key);}/*** 清除所有存储数据*/static clear(): void {this.getInstance().clear();}/*** 判断某个 key 是否存在* @param key 键名* @returns 存在返回 true,否则返回 false*/static has(key: string): boolean {return this.getInstance().has(key);}
}export default StorageUtil;// 示例使用
StorageUtil.set('username', 'Alice');
const username = StorageUtil.get('username', 'defaultUser');
console.log(`Username: ${username}`);
StorageUtil.delete('username');
console.log(StorageUtil.has('username')); // false
StorageUtil.clear();
5. 对比总结
特性 | 用户首选项 (Preferences) | 持久化存储 (PersistentStorage) |
---|---|---|
存储方式 | 轻量级键值对存储 | 适用于存储复杂数据 |
数据类型 | string , boolean , number | 复杂数据结构(JSON、列表等) |
数据量 | 小量数据 | 大量数据 |
适用场景 | 主题、语言、用户偏好 | 用户信息、缓存、离线数据 |
读写性能 | 读取速度快 | 适用于批量存储 |
数据持久性 | 持久化存储 | 持久化存储 |
6. 使用建议
- 如果只是存储 简单的设置数据,比如开关状态、主题模式,建议使用 Preferences。
- 如果需要存储 复杂对象(如 JSON 数据)或者 大量数据(如历史记录、缓存),建议使用 PersistentStorage。
当然如果你的数据规模较大,还可以考虑 数据库 (键值型数据库KVManager或者关系型数据库RdbStore) 进行存储,以提高查询和管理效率。