[Harmony]封装一个可视化的数据持久化工具

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 { isBlank } from '../extension/StringExtensions';/*** 配置项类型定义* @property key - 存储键名(建议使用下划线命名法)* @property defaultValue - 默认值(必须为字符串类型)* @property valueType - 值类型声明(用于类型校验)*/
interface StoragePreferenceItem {key: string;defaultValue: string;valueType: 'string';
}export class MFStorageManager {/*** 预定义配置项列表* @remark 使用readonly确保配置不可变* @remark valueType使用类型断言保证字面量类型*/private static readonly CONFIG_LIST: StoragePreferenceItem[] = [{ key: 'token', defaultValue: '', valueType: 'string' },{ key: 'user_id', defaultValue: '', valueType: 'string' },{ key: 'last_login', defaultValue: '', valueType: 'string' }];// 存储实例引用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 AppDataSingleton.getInstance().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> {if (!MFStorageManager.prefs) {ConsoleLog.error('请先调用StorageManager的initialize初始化');return "";}const target = MFStorageManager.CONFIG_LIST.find(item => item.key === key);if (!target) {ConsoleLog.error(`无效的配置项: ${key}`);return "";}return await MFStorageManager.prefs.get(target.key, target.defaultValue) as string;}/*** 更新配置值* @param key - 目标配置键* @param value - 新字符串值* @throws 未初始化或无效键名时抛出错误*/static async set(key: string, value: string): 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;}await MFStorageManager.prefs.put(target.key, value);await MFStorageManager.prefs.flush();// 同步更新单例数据const instance = AppDataSingleton.getInstance();switch(key) {case 'token': instance.token = value; break;case 'user_id': instance.user_id = value; break;case 'last_login': instance.last_login = value; break;}}/*** 选择性清除缓存数据* @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);// 同步重置单例数据const instance = AppDataSingleton.getInstance();switch(item.key) {case 'token': instance.token = item.defaultValue; break;case 'user_id': instance.user_id = item.defaultValue; break;case 'last_login': instance.last_login = item.defaultValue; break;}}await MFStorageManager.prefs.flush();ConsoleLog.log('缓存清理完成,忽略字段:', ignoredKeys);}
}/*** 用单例同步持久化的数据,避免每次使用数据都要去preferences中获取。*/
class AppDataSingleton {private static instance: AppDataSingleton;token: string = '';user_id: string = '';last_login: string = '';private constructor() {}public static getInstance(): AppDataSingleton {if (!AppDataSingleton.instance) {AppDataSingleton.instance = new AppDataSingleton();}return AppDataSingleton.instance;}/// 同步数据public async syncFromStorage() {this.token = await MFStorageManager.get('token');this.user_id = await MFStorageManager.get('user_id');this.last_login = await MFStorageManager.get('last_login');}/// 是否登录isLogin(): boolean {return isBlank(this.token) ? false : true;}}
export const AppStorageData = AppDataSingleton.getInstance();

自定义ConsoleLog为打印添加前缀,便于筛选出自己的打印的内容。

/// 为console打印添加前缀
class ConsoleLog {private static readonly PREFIX: string = 'gamin';static log(...args: (string | number | boolean | object)[]): void {console.log(ConsoleLog.PREFIX, ...args);}static error(...args: (string | number | boolean | object)[]): void {console.error(ConsoleLog.PREFIX, ...args);}static warn(...args: (string | number | boolean | object)[]): void {console.warn(ConsoleLog.PREFIX, ...args);}static debug(...args: (string | number | boolean | object)[]): void {console.debug(ConsoleLog.PREFIX, ...args);}static info(...args: (string | number | boolean | object)[]): void {console.info(ConsoleLog.PREFIX, ...args);}
}export default ConsoleLog;

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('user_id', 'user_123456');ConsoleLog.log('用户ID设置成功');})Button("获取用户ID").onClick(async () => {const userId = await MFStorageManager.get('user_id');ConsoleLog.log('当前用户ID:', userId);})Button('清除缓存(保留用户ID)').onClick(async () => {// 选择性清除配置try {await MFStorageManager.cleanData(['user_id']);ConsoleLog.log('缓存已清除(保留用户ID)');} catch (err) {ConsoleLog.error('清除失败:', err);}})}.height('100%').width('100%')}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/83692.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

利用html制作简历网页和求职信息网页

前言 大家好&#xff0c;我是maybe。今天下午初步学习了html的基础知识。做了两个小网页&#xff0c;一个网页是简历网页&#xff0c;一个网页是求职信息填写网页。跟大家分享一波~ 说明:我不打算上传图片。所以如果有朋友按照我的代码运行网页&#xff0c;会出现一个没有图片…

Vue 3 实现后端 Excel 文件流导出功能(Blob 下载详解)

&#x1f4a1; 本文以告警信息导出为例&#xff0c;介绍 Vue 3 中如何通过 Axios 调用后端接口并处理文件流&#xff0c;实现 Excel 自动下载功能。 &#x1f4d1; 目录 一、前言 二、后端接口说明 三、前端实现思路 四、导出功能完整代码 五、常见问题处理 六、效果展示 …

HarmonyOS AVPlayer 音频播放器

鸿蒙文档中心&#xff1a;使用AVPlayer播放视频(ArkTS)文档中心https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/video-playback 这张图描述的是 HarmonyOS AVPlayer 音频播放器的状态流转过程&#xff0c;展示了 AVPlayer 在不同状态之间的切换条件和关键操作…

Java面试场景:从音视频到AI应用的技术探讨

面试场景&#xff1a;音视频与AI应用技术的碰撞 在某互联网大厂的面试中&#xff0c;面试官王先生与求职者明哥展开了一场关于音视频技术与AI应用的对话。 第一轮提问&#xff1a;音视频场景 面试官&#xff1a;明哥&#xff0c;你能谈谈在音视频场景中&#xff0c;Spring B…

【深度学习】残差网络(ResNet)

如果按照李沐老师书上来&#xff0c;学完 VGG 后还有 NiN 和 GoogLeNet 要学&#xff0c;但是这两个我之前听都没听过&#xff0c;而且我看到我导师有发过 ResNet 相关的论文&#xff0c;就想跳过它们直接看后面的内容。 现在看来这不算是不踏实&#xff0c;因为李沐老师说如果…

Vue3学习(组合式API——父、子组件间通信详解)

目录 一、组合式API下的父组件传子组件。(自定义属性) &#xff08;1&#xff09;基本思想。 &#xff08;2&#xff09;核心注意点。(defineProps) &#xff08;3&#xff09;传递简单类型数据。 &#xff08;4&#xff09;传递对象类型数据。(v-bind"对象类型数据"…

W5500使用ioLibrary库创建TCP客户端

1、WIZnet全硬件TCP/IP协议栈 WIZnet全硬件TCP/IP协议栈,支持TCP,UDP,IPv4,ICMP,ARP,IGMP以及PPPoE协议。 以太网&#xff1a;支持BSD和WIZCHIP&#xff08;W5500/W5300/W5200/W5100/W5100S&#xff09;的SOCKET APIs驱动程序。 互联网&#xff1a; DHCP客户端 DNS客户端 FTP客…

管理Oracle Data Guard的最佳实践

Oracle Data Guard的中文名字叫数据卫士&#xff0c;顾名思义&#xff0c;它是生产库的一道保障。所以管理Data Guard是DBA的一项重要工作之一&#xff0c;管理Data Guard时主要有以下几个注意点需要引起重视。 备份库的归档日志积压 一般情况下&#xff0c;生产库的归档日志是…

BootCDN介绍(Bootstrap主导的前端开源项目免费CDN加速服务)

文章目录 BootCDN前端开源项目CDN加速服务全解析什么是BootCDN技术原理与架构CDN技术基础BootCDN架构特点1. 全球分布式节点网络2. 智能DNS解析系统3. 高效缓存管理机制4. 自动同步更新机制5. HTTPS和HTTP/2协议支持 BootCDN的核心优势速度与稳定性开源免费资源丰富度技术规范遵…

2025 Java 微信小程序根据code获取openid,二次code获取手机号【工具类】拿来就用

一、controller调用 /*** 登录** author jiaketao* since 2024-04-10*/ RestController RequestMapping("/login") public class LoginController {/*** 【小程序】登录获取session_key和openid** param code 前端传code* return*/GetMapping("/getWXSessionKe…

软件架构风格系列(3):管道 - 过滤器架构

文章目录 前言一、从生活场景到架构原理&#xff0c;看懂管道 - 过滤器的核心逻辑&#xff08;一&#xff09;什么是管道 - 过滤器架构&#xff1f;&#xff08;二&#xff09;核心组件拆解 二、架构设计图&#xff1a;一图看懂管道 - 过滤器架构全貌三、Java 示例代码&#xf…

【VIM】vim 常用命令

文章目录 插入模式光标移动拷贝/粘贴/删除/撤销块操作分屏代码缩进命令组合使用其他PowerVim 前言&#xff1a;本文内容大部分摘抄自酷壳和博客园   –   CoolShell – 陈皓   博客园 – 易先讯 插入模式 a → 在光标后插入o → 在当前行后插入一个新行O → 在当前行前插…

polarctf-web-[简单rce]

考点&#xff1a; (1)RCE(eval函数) (2)执行函数(passthru函数) (3)/顶级(根)目录查看 (4)sort排序查看函数 题目来源&#xff1a;Polarctf-web-[简单rce] 解题&#xff1a; 代码审计 <?php/*​PolarD&N CTF​*/highlight_file(__FILE__);function no($txt){ # …

HarmonyOs开发之———使用HTTP访问网络资源

谢谢关注&#xff01;&#xff01; 前言&#xff1a;上一篇文章主要介绍HarmonyOs开发之———Video组件的使用:HarmonyOs开发之———Video组件的使用_华为 video标签查看-CSDN博客 HarmonyOS 网络开发入门&#xff1a;使用 HTTP 访问网络资源 HarmonyOS 作为新一代智能终端…

Vue 图片预览功能(含缩略图)

众所周知&#xff0c;常见的组件库如Element、Ant Design&#xff0c;自带的图片预览功能都没有缩略图&#xff0c;所以 需要单独封装一个图片预览的服务。 第三方库&#xff1a;v-viewer 安装&#xff1a; npm install v-viewer viewerjs 若使用报错&#xff0c;可安装指定…

手写tomcat:基本功能实现(4)

逻辑架构 HTTP 请求与 Socket&#xff1a; 左侧的 “HTTP 请求” 箭头指向 “socket”&#xff0c;表示客户端发送的 HTTP 请求通过 socket 传输到服务器。Socket 负责接收请求&#xff0c;并提取出其中的 请求路径&#xff08;如 /first&#xff09;和 请求方法&#xff08;如…

jvm安全点(一)openjdk17 c++源码垃圾回收安全点信号函数处理线程阻塞

1. 信号处理入口​​ ​​JVM_HANDLE_XXX_SIGNAL​​ 是 JVM 处理信号的统一入口&#xff0c;负责处理 SIGSEGV、SIGBUS 等信号。​​javaSignalHandler​​ 是实际注册到操作系统的信号处理函数&#xff0c;直接调用 JVM_HANDLE_XXX_SIGNAL。 ​​2. 安全点轮询页的识别​​ …

微信小程序:封装表格组件并引用

一、效果 封装表格组件,在父页面中展示表格组件并显示数据 二、表格组件 1、创建页面 创建一个components文件夹,专门用于存储组件的文件夹 创建Table表格组件 2、视图层 (1)表头数据 这里会从父组件中传递表头数据,这里为columns,后续会讲解数据由来 循环表头数组,…

【FMC216】基于 VITA57.1 的 2 路 TLK2711 发送、2 路 TLK2711 接收 FMC 子卡模块

产品概述 FMC216 是一款基于 VITA57.1 标准规范的 2 路 TLK2711 接收、2 路 TLK2711 发送 FMC 子卡模块。该板卡支持 2 路 TLK2711 数据的收发&#xff0c;支持线速率 1.6Gbps&#xff0c;经过 TLK2711 高速串行收发器&#xff0c;可以将 1.6Gbps 的高速串行数据解串为 16 位并…

K8S Gateway API 快速开始、胎教级教程

假设有如下三个节点的 K8S 集群&#xff1a; ​​ k8s31master 是控制节点 k8s31node1、k8s31node2 是工作节点 容器运行时是 containerd 一、Gateway 是什么 背景和目的 入口&#xff08;Ingress&#xff09;目前已停止更新。新的功能正在集成至网关 API 中。在 Kubernetes …