[Harmony]封装一个可视化的数据持久化工具
本文介绍了在HarmonyOS应用中如何添加权限、封装数据持久化工具及其使用示例。首先,在module.json5文件中声明应用所需的分布式数据同步权限,并配置使用场景。接着,封装了一个基于@ohos.data.preferences的可视化数据持久化工具MFStorageManager,支持初始化、获取、更新和选择性清除缓存数据等功能。工具类中还定义了一个自定义的ConsoleLog类,用于在控
·
1.添加权限
在module.json5文件中添加权限
// 声明应用需要请求的权限列表
"requestPermissions": [
{
"name": "ohos.permission.DISTRIBUTED_DATASYNC", // 权限名称:分布式数据同步权限
"reason": "$string:distributed_database_reason",// 权限使用原因说明(引用string资源)
"usedScene": { // 权限使用场景配置
"abilities": ["MFStorageManager"], // 声明需要使用该权限的Ability列表
"when": "always" // 权限调用时机:always表示始终需要
}
}
]
/resources/base/element/string.json
{
"string": [
{
"name": "distributed_database_reason",
"value": "用于保存用户配置信息"
}
]
}
2.封装可视化数据持久工具
import preferences from '@ohos.data.preferences';
import { BusinessError } from '@ohos.base';
import ConsoleLog from '../extension/ConsoleLog';
import { AppUserDataShare } from './MFUserDataShared';
/**
* 配置项类型定义
* @property key - 存储键名(建议使用下划线命名法)
* @property defaultValue - 默认值(必须为字符串类型)
* @property valueType - 值类型声明(用于类型校验)
*/
interface StoragePreferenceItem {
key: string;
defaultValue: string | number | boolean;
valueType: 'string' | 'number' | 'boolean';
}
export class MFStorageManager {
/**
* 预定义配置项列表
* @remark 使用readonly确保配置不可变
* @remark valueType使用类型断言保证字面量类型
*/
private static readonly CONFIG_LIST: StoragePreferenceItem[] = [
{ key: 'token', defaultValue: '', valueType: 'string' },
{ key: 'sof_id', defaultValue: '', valueType: 'string' },
{ key: 'time_channel', defaultValue: 1, valueType: 'number' }
];
// 存储实例引用
private static prefs: preferences.Preferences | null = null;
/**
* 初始化配置管理器
* @param context - 应用上下文对象
* @throws 当底层存储初始化失败时记录错误日志
*/
static async initialize(context: Context): Promise<void> {
try {
MFStorageManager.prefs = await preferences.getPreferences(context, 'app_config');
await MFStorageManager.checkDefaults();
await AppUserDataShare.syncFromStorage();
ConsoleLog.log('配置管理器初始化完成');
} catch (err) {
ConsoleLog.error(`初始化失败: ${(err as BusinessError).message}`);
}
}
/**
* 配置项默认值检查
* @remark 自动填充未初始化的配置项
* @private 内部方法
*/
private static async checkDefaults(): Promise<void> {
if (!MFStorageManager.prefs) return;
for (const item of MFStorageManager.CONFIG_LIST) {
const current = await MFStorageManager.prefs.get(item.key, item.defaultValue);
if (current === item.defaultValue) {
await MFStorageManager.prefs.put(item.key, item.defaultValue);
}
}
await MFStorageManager.prefs.flush();
}
/**
* 获取配置值
* @param key - 目标配置键
* @returns 配置值的字符串形式
* @throws 未初始化或无效键名时抛出错误
*/
static async get(key: string): Promise<string | number | boolean> {
if (!MFStorageManager.prefs) {
ConsoleLog.error('请先调用StorageManager的initialize初始化');
return "";
}
const target = MFStorageManager.CONFIG_LIST.find(item => item.key === key);
if (!target) {
ConsoleLog.error(`无效的配置项: ${key}`);
return "";
}
try {
let res = await MFStorageManager.prefs.get(target.key, target.defaultValue) as string | number | boolean;
return res
} catch (e) {
ConsoleLog.log('获取配置报错')
return ''
}
}
/**
* 更新配置值
* @param key - 目标配置键
* @param value - 新字符串值
* @throws 未初始化或无效键名时抛出错误
*/
static async set(key: string, value: string | number | boolean): Promise<void> {
if (!MFStorageManager.prefs) {
ConsoleLog.error('请先调用StorageManager的initialize初始化');
return;
}
const target = MFStorageManager.CONFIG_LIST.find(item => item.key === key);
if (!target) {
ConsoleLog.error(`无效的配置项: ${key}`);
return;
}
try {
await MFStorageManager.prefs.put(target.key, value);
await MFStorageManager.prefs.flush();
// 同步更新单例数据
await AppUserDataShare.syncFromStorage();
} catch (e) {
ConsoleLog.error('更新配置报错')
}
}
/**
* 选择性清除缓存数据
* @param ignoredKeys - 需要保留的键名数组
* @remark 保留的配置项将保持当前值不变
*/
static async cleanData(ignoredKeys: string[] = []): Promise<void> {
if (!MFStorageManager.prefs) {
ConsoleLog.error('请先调用StorageManager的initialize初始化');
return;
}
// 获取需要清理的配置项(排除忽略字段)
const needCleanItems = MFStorageManager.CONFIG_LIST.filter(
item => !ignoredKeys.includes(item.key)
);
// 批量重置为默认值
for (const item of needCleanItems) {
await MFStorageManager.prefs.put(item.key, item.defaultValue);
}
await MFStorageManager.prefs.flush();
ConsoleLog.log('缓存清理完成,忽略字段:', ignoredKeys);
// 同步重置单例数据
await AppUserDataShare.syncFromStorage();
}
}
同步缓存数据到单例,便于实时使用。
import { MFStorageManager } from "./MFStorageManager";
/**
* 用单例同步持久化的数据,避免每次使用数据都要去preferences中获取。
*/
class MFUserDataShared {
private static instance: MFUserDataShared;
token: string = '';
sofId: string = '';
timeChannel: number = 1;
private constructor() {}
public static getInstance(): MFUserDataShared {
if (!MFUserDataShared.instance) {
MFUserDataShared.instance = new MFUserDataShared();
}
return MFUserDataShared.instance;
}
/// 同步数据-缓存信息
public async syncFromStorage() {
let tempToken = await MFStorageManager.get('token');
if (typeof tempToken === 'string') {
this.token = tempToken
}
let tempSofId = await MFStorageManager.get('sof_id');
if (typeof tempSofId === 'string') {
this.sofId = tempSofId
}
let tempTimeChannel = await MFStorageManager.get('time_channel');
if (typeof tempTimeChannel === 'number') {
this.timeChannel = tempTimeChannel
}
}
/// 清除缓存数据
private cleanData() {
this.token = ''
this.sofId = ''
this.timeChannel = 1
}
}
export const AppUserDataShare = MFUserDataShared.getInstance();
3.使用示例
import { MFStorageManager } from '../support/data/MFStorageManager';
import common from '@ohos.app.ability.common';
import ConsoleLog from '../support/extension/ConsoleLog';
@Entry
@Component
struct Index {
private context = getContext(this) as common.UIAbilityContext;
aboutToAppear() {
if (!this.context) {
ConsoleLog.error('无效的上下文对象');
return;
}
// 初始化配置管理器
MFStorageManager.initialize(this.context)
}
build() {
Column() {
Button("设置用户ID")
.onClick(() => {
MFStorageManager.set('sofId', 'user_123456');
ConsoleLog.log('用户ID设置成功');
})
Button("获取用户ID")
.onClick(async () => {
const userId = await MFStorageManager.get('sofId');
ConsoleLog.log('当前用户ID:', userId);
})
Button('清除缓存(保留用户ID)')
.onClick(async () => {
// 选择性清除配置
try {
await MFStorageManager.cleanData(['sofId']);
ConsoleLog.log('缓存已清除(保留用户ID)');
} catch (err) {
ConsoleLog.error('清除失败:', err);
}
})
}
.height('100%')
.width('100%')
}
}
更多推荐
所有评论(0)