技术栈:HarmonyOS 5.0 + ArkTS + @ohos.data.preferences
适用场景:用户设置、历史记录、应用状态保存
前言
在应用开发中,数据持久化是必不可少的功能。HarmonyOS提供了@ohos.data.preferences模块用于轻量级数据存储。本文将介绍如何封装一个通用的首选项工具类。
一、Preferences vs 关系型数据库
| 特性 | Preferences | 关系型数据库 |
|---|---|---|
| 数据量 | 小(KB级) | 大(MB级) |
| 数据结构 | 键值对 | 表结构 |
| 查询能力 | 简单 | 复杂SQL |
| 适用场景 | 用户设置 | 业务数据 |
二、工具类封装
2.1 基础工具类
typescript
import dataPreferences from '@ohos.data.preferences';
import common from '@ohos.app.ability.common';
export class PreferencesUtil {
private static readonly PREFERENCES_NAME = 'app_preferences';
private static preferences: dataPreferences.Preferences | null = null;
/**
* 初始化(必须在EntryAbility.onCreate中调用)
*/
static async init(context: common.UIAbilityContext): Promise<void> {
try {
PreferencesUtil.preferences = await dataPreferences.getPreferences(
context,
PreferencesUtil.PREFERENCES_NAME
);
console.info('PreferencesUtil: 初始化成功');
} catch (err) {
console.error('PreferencesUtil: 初始化失败', err);
}
}
static async putString(key: string, value: string): Promise<void> {
if (!PreferencesUtil.preferences) return;
await PreferencesUtil.preferences.put(key, value);
await PreferencesUtil.preferences.flush();
}
static async getString(key: string, defaultValue: string = ''): Promise<string> {
if (!PreferencesUtil.preferences) return defaultValue;
return await PreferencesUtil.preferences.get(key, defaultValue) as string;
}
static async putNumber(key: string, value: number): Promise<void> {
if (!PreferencesUtil.preferences) return;
await PreferencesUtil.preferences.put(key, value);
await PreferencesUtil.preferences.flush();
}
static async getNumber(key: string, defaultValue: number = 0): Promise<number> {
if (!PreferencesUtil.preferences) return defaultValue;
return await PreferencesUtil.preferences.get(key, defaultValue) as number;
}
static async putBoolean(key: string, value: boolean): Promise<void> {
if (!PreferencesUtil.preferences) return;
await PreferencesUtil.preferences.put(key, value);
await PreferencesUtil.preferences.flush();
}
static async getBoolean(key: string, defaultValue: boolean = false): Promise<boolean> {
if (!PreferencesUtil.preferences) return defaultValue;
return await PreferencesUtil.preferences.get(key, defaultValue) as boolean;
}
static async delete(key: string): Promise<void> {
if (!PreferencesUtil.preferences) return;
await PreferencesUtil.preferences.delete(key);
await PreferencesUtil.preferences.flush();
}
}
2.2 复杂对象存储
typescript
export interface HearingTestResult {
id: string;
timestamp: number;
maxFrequency: number;
hearingAge: number;
level: string;
}
export class TestHistoryManager {
private static readonly KEY = 'hearing_test_history';
static async saveResult(result: HearingTestResult): Promise<void> {
const history = await TestHistoryManager.getHistory();
history.push(result);
// 只保留最近20条
const trimmed = history.slice(-20);
await PreferencesUtil.putString(this.KEY, JSON.stringify(trimmed));
}
static async getHistory(): Promise<HearingTestResult[]> {
const str = await PreferencesUtil.getString(this.KEY, '[]');
try {
return JSON.parse(str) as HearingTestResult[];
} catch {
return [];
}
}
}
2.3 键名常量管理
typescript
export const PreferencesKeys = {
VIBRATION_ENABLED: 'vibration_enabled',
VOLUME_LEVEL: 'volume_level',
THEME_MODE: 'theme_mode',
USE_COUNT: 'use_count',
TOTAL_DURATION: 'total_duration',
ONBOARDING_COMPLETED: 'onboarding_completed',
};
三、在EntryAbility中初始化
typescript
import { UIAbility } from '@ohos.app.ability.UIAbility';
import { PreferencesUtil } from 'common';
export default class EntryAbility extends UIAbility {
async onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): Promise<void> {
await PreferencesUtil.init(this.context);
}
}
四、使用示例
typescript
// 保存用户设置
await PreferencesUtil.putBoolean(PreferencesKeys.VIBRATION_ENABLED, true);
await PreferencesUtil.putNumber(PreferencesKeys.VOLUME_LEVEL, 80);
// 读取用户设置
const vibrationEnabled = await PreferencesUtil.getBoolean(PreferencesKeys.VIBRATION_ENABLED, true);
const volumeLevel = await PreferencesUtil.getNumber(PreferencesKeys.VOLUME_LEVEL, 80);
// 保存复杂对象
const result: HearingTestResult = {
id: Date.now().toString(),
timestamp: Date.now(),
maxFrequency: 16000,
hearingAge: 25,
level: '正常'
};
await TestHistoryManager.saveResult(result);
五、避坑指南
- 初始化时机 :必须在
EntryAbility.onCreate中初始化 - flush调用 :每次
put后都要调用flush() - JSON序列化 :复杂对象需要
JSON.stringify/JSON.parse - 数据量限制:Preferences适合小数据,大数据用关系型数据库
- 异步处理 :所有操作都是异步的,注意使用
await
总结
本文封装了一个通用的Preferences工具类,支持基础类型和复杂对象的存储。在实际项目中,这个工具类被用于保存用户设置、测试历史、使用统计等数据。