HarmonyOs应用《重要日》开发第6篇 - 数据持久化存储
本篇深入剖析 ImportantDays 项目的数据持久化方案——基于 HarmonyOS ArkData 模块的 Preferences 轻量级存储以及 PreferenceUtil 工具类的单例封装。一、HarmonyOS 数据存储方案对比HarmonyOS 提供了多种数据存储方案方案适用场景特点Preferences轻量级 KV 数据同步操作适合少量数据关系型数据库 (RDB)结构化数据SQLite支持复杂查询分布式数据 (DDS)跨设备同步多设备数据一致性文件存储大文件直接读写文件系统ImportantDays 选择 Preferences 的原因数据量小通常几十条重要日数据结构简单JSON 字符串不需要复杂查询同步操作代码简洁二、PreferenceUtil 工具类2.1 完整实现// utils/PreferenceUtil.etsimport{preferences}fromkit.ArkData;import{common}fromkit.AbilityKit;import{Logger}from./Logger;exportclassPreferenceUtil{privatestaticpreferenceRecord:Mapstring,PreferenceUtilnewMap();privatedataPreferences:preferences.Preferences|nullnull;privateconstructor(context:Context,fileName:string){preferences.removePreferencesFromCacheSync(context,fileName);this.dataPreferencespreferences.getPreferencesSync(context,{name:fileName});Logger.info(PreferenceUtil:${fileName}init:${this.dataPreferences!null});}publicstaticgetInstance(context?:Context,fileName:stringdefault):PreferenceUtil{if(PreferenceUtil.preferenceRecord.has(fileName)){returnPreferenceUtil.preferenceRecord.get(fileName)!;}constctx:Contextcontext||getContext()ascommon.UIAbilityContext;constpreferenceUtil:PreferenceUtilnewPreferenceUtil(ctx,fileName);PreferenceUtil.preferenceRecord.set(fileName,preferenceUtil);returnpreferenceUtil;}publicgetPreferences():preferences.Preferences|null{returnthis.dataPreferences;}publicput(key:string,value:object|string|number|boolean):void{if(!this.dataPreferences){Logger.info(PreferenceUtil: dataPreferences is null);return;}try{this.dataPreferences.putSync(key,value);this.dataPreferences.flushSync();Logger.info(PreferenceUtil: put:${key});}catch(e){Logger.error(PreferenceUtil: put error:${JSON.stringify(e)});}}publicget(key:string,defaultValue:object|string|number|boolean):object|string|number|boolean{if(!this.dataPreferences){returndefaultValue;}try{returnthis.dataPreferences.getSync(key,defaultValue)asobject|string|number|boolean;}catch(e){Logger.error(PreferenceUtil: get error:${JSON.stringify(e)});returndefaultValue;}}publicdelete(key:string):void{if(!this.dataPreferences){return;}try{this.dataPreferences.deleteSync(key);this.dataPreferences.flushSync();Logger.info(PreferenceUtil: delete:${key});}catch(e){Logger.error(PreferenceUtil: delete error:${JSON.stringify(e)});}}}2.2 设计要点单例模式按文件名区分privatestaticpreferenceRecord:Mapstring,PreferenceUtilnewMap();publicstaticgetInstance(context?:Context,fileName:stringdefault):PreferenceUtil{if(PreferenceUtil.preferenceRecord.has(fileName)){returnPreferenceUtil.preferenceRecord.get(fileName)!;}// ...创建新实例}使用Map按fileName维护多个实例每个文件对应一个PreferenceUtil实例。缓存清理privateconstructor(context:Context,fileName:string){preferences.removePreferencesFromCacheSync(context,fileName);this.dataPreferencespreferences.getPreferencesSync(context,{name:fileName});}在创建实例前先从缓存中移除确保获取的是最新实例。这是处理开发热重载时缓存残留的关键。同步 APIthis.dataPreferences.putSync(key,value);this.dataPreferences.flushSync();使用同步 API 而非异步简化调用方代码。对于轻量级数据同步操作的性能影响可以忽略。容错处理publicput(key:string,value:object|string|number|boolean):void{if(!this.dataPreferences){Logger.info(PreferenceUtil: dataPreferences is null);return;}try{this.dataPreferences.putSync(key,value);this.dataPreferences.flushSync();}catch(e){Logger.error(PreferenceUtil: put error:${JSON.stringify(e)});}}所有操作都包含 try-catch确保存储异常不会导致应用崩溃。三、在 MainViewModel 中使用3.1 初始化// viewmodel/MainViewModel.etspublicasyncinit(context:Context):Promisevoid{this.prefUtilPreferenceUtil.getInstance(context,AppConstants.PREF_FILE);this.loadDays();}常量定义// common/Constants.etsexportclassAppConstants{publicstaticreadonlyPREF_FILE:stringimportant_days;publicstaticreadonlyPREF_KEY_DAYS:stringimportant_day_list;}3.2 加载数据privateloadDays():void{if(!this.prefUtil)return;constjsonStrthis.prefUtil.get(AppConstants.PREF_KEY_DAYS,[])asstring;try{constarr:string[]JSON.parse(jsonStr);this.dayListarr.map((json:string)ImportantDay.fromJSON(json)).filter((day:ImportantDay|null)day!null)asImportantDay[];}catch(e){Logger.error(MainViewModel: loadDays error:${JSON.stringify(e)});this.dayList[];}}3.3 保存数据privatesaveDays():void{if(!this.prefUtil)return;constarr:string[]this.dayList.map((day:ImportantDay)day.toJSON());this.prefUtil.put(AppConstants.PREF_KEY_DAYS,JSON.stringify(arr));}3.4 数据存储格式Preferences 中存储的数据结构文件: important_days 键: important_day_list 值: [{\id\:\1690000000000_3456\,\title\:\妈妈生日\,\date\:\2026-03-15\,\description\:\记得买蛋糕\,\colorIndex\:5,\countMode\:0,\repeatType\:1,\advanceDays\:3,\isPinned\:true,\createdAt\:1690000000000,\updatedAt\:1690000000000}]外层是一个 JSON 数组字符串每个元素是ImportantDay.toJSON()的结果。这种嵌套设计的原因Preferences 的putSync只支持基本类型string、number、boolean和 string将数组序列化为字符串存储可以一次性保存所有数据加载时一次性反序列化减少 IO 操作四、putSync 与 flushSync 的区别this.dataPreferences.putSync(key,value);// 写入内存缓存this.dataPreferences.flushSync();// 持久化到文件putSync将数据写入内存缓存速度极快flushSync将内存缓存的数据刷写到磁盘文件确保数据持久化两者必须配合使用。如果只调用putSync而不flushSync数据在应用关闭后会丢失。五、removePreferencesFromCacheSync 的作用preferences.removePreferencesFromCacheSync(context,fileName);这行代码在构造函数中调用用于从内存缓存中移除指定文件的 Preferences 实例。这在以下场景中很重要开发阶段热重载DevEco Studio 热重载时旧的 Preferences 实例可能还留在缓存中多实例场景确保每次getInstance获取的是最新状态数据同步防止缓存中的脏数据影响新实例六、存储方案扩展思考6.1 当前方案的局限全量保存每次修改都保存整个列表数据量大时可能有性能问题无索引查询某日的重要日需要遍历整个列表无事务多步操作不具备原子性6.2 如果使用 RDB如果未来数据量增长可以迁移到关系型数据库CREATETABLEimportant_days(idTEXTPRIMARYKEY,titleTEXTNOTNULL,dateTEXTNOTNULL,descriptionTEXT,color_indexINTEGERDEFAULT0,count_modeINTEGERDEFAULT0,repeat_typeINTEGERDEFAULT0,advance_daysINTEGERDEFAULT0,is_pinnedINTEGERDEFAULT0,created_atINTEGER,updated_atINTEGER);CREATEINDEXidx_dateONimportant_days(date);CREATEINDEXidx_pinnedONimportant_days(is_pinned);但当前 Preferences 方案对于这个应用规模完全够用简单可靠。七、小结本篇详细介绍了 ImportantDays 项目的数据持久化方案。PreferenceUtil 通过单例模式封装 Preferences API提供简洁的get/put/delete接口。MainViewModel 在每次 CRUD 操作后自动调用saveDays()持久化数据确保数据不丢失。

相关新闻

LMK61E0M DCXO实战:从I2C配置到环路滤波,打造70.656MHz高精度时钟

LMK61E0M DCXO实战:从I2C配置到环路滤波,打造70.656MHz高精度时钟

1. 项目概述与核心价值 在高速数字系统、通信设备乃至精密测量仪器中,一个稳定、纯净且可精确调控的时钟信号,往往是整个系统稳定运行的“心跳”。无论是确保数据在光纤中无误传输,还是让ADC/DAC芯片精准采样,亦或是让多块FPGA板卡…

2026/7/15 23:58:25 阅读更多 →
深信服防火墙开局+访问控制策略+SNAT+DNAT+策略路由配置

深信服防火墙开局+访问控制策略+SNAT+DNAT+策略路由配置

1.防火墙加电,管理接口MANAGE连接网线到PC2.PC配置地址10.251.251.252/24,打开浏览器输入默认地址https://10.251.251.251/3.输入默认用户名密码admin/admin,登录到首页4.首次登录提示让修改密码5.区域配置查看默认存在的区域配置新区域并添加…

2026/7/15 23:56:25 阅读更多 →
LookML+BigQuery构建AI分析代理的语义层实践

LookML+BigQuery构建AI分析代理的语义层实践

1. 项目概述:当LookML遇上BigQuery,AI分析代理的语义层新解法你有没有遇到过这样的场景:业务同学急吼吼地跑来问“上个月华东区高净值客户的复购率是多少”,数据工程师刚把SQL写到一半,发现这个“高净值客户”的定义在…

2026/7/15 23:52:24 阅读更多 →

最新新闻

如何简单快速管理《博德之门3》模组:BG3ModManager完整使用指南

如何简单快速管理《博德之门3》模组:BG3ModManager完整使用指南

如何简单快速管理《博德之门3》模组:BG3ModManager完整使用指南 【免费下载链接】BG3ModManager A mod manager for Baldurs Gate 3. This is the only official source! 项目地址: https://gitcode.com/gh_mirrors/bg/BG3ModManager 还在为《博德之门3》模组…

2026/7/16 1:02:46 阅读更多 →
2026想节能,中央空调商家选哪家

2026想节能,中央空调商家选哪家

家人们,每到夏天和冬天,中央空调就成了咱们生活里的必备神器。但用久了,各种问题也慢慢浮现出来。就说我之前用的那个中央空调,制冷制热效果差不说,能耗还特别高,每个月的电费账单都让我肉疼。而且有时候屋…

2026/7/16 1:00:44 阅读更多 →
GitHub、Vercel 和 Firestore 技术栈:提升开发速度、消除运维烦恼的“免运维”之选

GitHub、Vercel 和 Firestore 技术栈:提升开发速度、消除运维烦恼的“免运维”之选

为速度而生的“免运维”技术栈如今,应用开发者可从众多架构解决方案中做选择,云计算革命中涌现的强大折中技术已成熟,这里探讨整合 GitHub、Vercel 和 Firestore 三项技术。它们结合能满足多应用场景需求,缩短开发与部署距离。若追…

2026/7/16 0:58:43 阅读更多 →
【华中师范大学、华南师范大学联合主办 | SPIE出版,往届快至会后2.5个月见刊,刊后1.5个月检索 |邀请多位高校专家作主题报告】第五届图像处理、目标检测与跟踪国际学术会议(IPODT 2026)

【华中师范大学、华南师范大学联合主办 | SPIE出版,往届快至会后2.5个月见刊,刊后1.5个月检索 |邀请多位高校专家作主题报告】第五届图像处理、目标检测与跟踪国际学术会议(IPODT 2026)

历史优秀:往届快至会后2.5个月见刊,见刊后1.5个月检索; 单位背书:华中师范大学、华南师范大学联合主办,学术背景扎实,可放心投稿! 阵容权威:邀请多位高校专家作主题报告&#xff0…

2026/7/16 0:54:41 阅读更多 →
计科毕设易上手项目选题分享

计科毕设易上手项目选题分享

1 引言 毕业设计是大家学习生涯的最重要的里程碑,它不仅是对四年所学知识的综合运用,更是展示个人技术能力和创新思维的重要过程。选择一个合适的毕业设计题目至关重要,它应该既能体现你的专业能力,又能满足实际应用需求&#xf…

2026/7/16 0:52:41 阅读更多 →
如何高效使用BG3ModManager:博德之门3模组管理完整指南

如何高效使用BG3ModManager:博德之门3模组管理完整指南

如何高效使用BG3ModManager:博德之门3模组管理完整指南 【免费下载链接】BG3ModManager A mod manager for Baldurs Gate 3. This is the only official source! 项目地址: https://gitcode.com/gh_mirrors/bg/BG3ModManager 作为《博德之门3》玩家&#xff…

2026/7/16 0:52:41 阅读更多 →

日新闻

HarmonyOs应用《重要日》开发第6篇 - 数据持久化存储

HarmonyOs应用《重要日》开发第6篇 - 数据持久化存储

本篇深入剖析 ImportantDays 项目的数据持久化方案——基于 HarmonyOS ArkData 模块的 Preferences 轻量级存储,以及 PreferenceUtil 工具类的单例封装。一、HarmonyOS 数据存储方案对比 HarmonyOS 提供了多种数据存储方案:方案适用场景特点Preferences轻…

2026/7/16 0:08:27 阅读更多 →
Python实现跨境电商商品图批量翻译教程

Python实现跨境电商商品图批量翻译教程

一、问题引入做跨境电商的卖家朋友,你是否遇到过这样的困扰?每次上架新品到亚马逊、Shopee或Lazada等平台,都需要处理大量商品图片的多语言版本。比如上架200款衣服,每款需要翻译成英语、日语、韩语等5种语言,这意味着…

2026/7/16 0:08:27 阅读更多 →
鸿蒙 7 新特性实战①:从 0 到 1 掌握 @kit 标准导入规范

鸿蒙 7 新特性实战①:从 0 到 1 掌握 @kit 标准导入规范

从鸿蒙 7(HarmonyOS NEXT)开始,官方全面完成了从 ohos.* 零散模块到 kit.* 领域套件的体系重构。对开发者来说,第一道门槛不是 API 用法变化,而是统一的导入规范——旧体系默认导入、解构导入混用的混乱局面被彻底终结…

2026/7/16 0:10:29 阅读更多 →

周新闻

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨 在一个阳光明媚的上午,互联网大厂的面试官坐在桌前,准备迎接他的面试候选人——燕双非,一个以搞笑和幽默著称的程序员。第一轮提问 面试官:燕双非,作…

2026/7/15 21:09:01 阅读更多 →
车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估

车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估

车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估在智能驾驶和车联网技术快速发展的今天,车载以太网作为新一代车载网络的核心传输技术,其物理层性能直接决定了数据传输的可靠性和稳定性。1000BASE-T1作为当前主流的…

2026/7/15 19:42:20 阅读更多 →
VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战,5步完成Keil工程转换

VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战,5步完成Keil工程转换

VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战指南嵌入式开发领域正经历一场工具链的静默革命。当传统Keil用户首次打开VSCode的扩展市场搜索EIDE时,往往会惊讶于这个看似简单的插件竟能重构十余年的开发习惯。本文将揭示如何用五个精准步骤&#xff0…

2026/7/15 17:52:08 阅读更多 →

月新闻