当前位置: 首页 > news >正文

OpenHarmony Preferences 本地持久化存储实战详解

一、前言

在 OpenHarmony 应用开发中,Preferences 偏好存储常用于保存轻量键值对数据:用户配置、登录状态、开关设置、缓存标识等,数据持久保存在本地,应用重启、设备关机后数据不丢失。相较于数据库,Preferences 使用简单、专注字符串 / 数字 / 布尔等基础类型,是项目高频本地存储方案。本篇完整讲解 API 用法、存取、删除、同步 / 异步操作,搭配落地代码。

依赖模块:@ohos.data.preferences

二、核心基础概念

  1. Preferences 实例:以文件名区分数据库,一个文件对应一套独立键值数据;
  2. 存储数据类型:支持string、number、boolean、Array<string>四种;
  3. 数据落盘:写入数据后必须调用flush()才会持久化写入磁盘,否则只在内存。

三、前置导入

ets

import preferences from '@ohos.data.preferences' import common from '@ohos.app.ability.common'

获取上下文 Context(Ability 上下文,存储必备参数)。

四、基础 CRUD 案例

4.1 封装获取 Preferences 工具对象

ets

// 获取偏好存储实例 async function getPrefer(context: common.UIAbilityContext, fileName: string) { let prefer = await preferences.getPreferences(context, fileName) return prefer }

4.2 写入 & 保存数据

ets

@Entry @Component struct PreWriteDemo { // 上下文 context = getContext(this) as common.UIAbilityContext async saveData() { // 打开userinfo.xml存储文件 let prefer = await getPrefer(this.context, "userinfo") // 存入多组键值 prefer.putSync("username", "Harmony开发者") prefer.putSync("age", 22) prefer.putSync("isLogin", true) prefer.putSync("hobby", ["编程", "嵌入式", "鸿蒙开发"]) // 关键:持久化落地磁盘 await prefer.flush() console.info("数据保存成功") } build() { Column() { Button("保存用户信息") .width(200) .onClick(() => this.saveData()) } .width("100%") .height("100%") .justifyContent(FlexAlign.Center) } }

4.3 读取本地存储数据

ets

@Entry @Component struct PreReadDemo { @State name: string = "" @State age: number = 0 @State loginStat: boolean = false context = getContext(this) as common.UIAbilityContext async readData() { let prefer = await getPrefer(this.context, "userinfo") // 参数:键名、默认值(无数据时返回默认) this.name = prefer.getSync("username", "未知用户") this.age = prefer.getSync("age", 0) this.loginStat = prefer.getSync("isLogin", false) } build() { Column({ space: 15 }) { Button("读取存储数据").onClick(() => this.readData()) Text(`用户名:${this.name}`).fontSize(18) Text(`年龄:${this.age}`).fontSize(18) Text(`登录状态:${this.loginStat ? "已登录" : "未登录"}`).fontSize(18) } .padding(30) .width("100%") .height("100%") .justifyContent(FlexAlign.Center) } }

4.4 删除指定键、清空全部数据

ets

@Entry @Component struct PreDelDemo { context = getContext(this) as common.UIAbilityContext // 删除单个key async delKey() { let prefer = await getPrefer(this.context, "userinfo") prefer.deleteSync("age") await prefer.flush() console.info("age字段删除完成") } // 清空当前文件所有数据 async clearAll() { let prefer = await getPrefer(this.context, "userinfo") prefer.clearSync() await prefer.flush() console.info("全部数据清空") } build() { Column({ space:20 }) { Button("删除age字段").onClick(()=>this.delKey()) Button("清空全部数据").onClick(()=>this.clearAll()) } .width("100%") .height("100%") .justifyContent(FlexAlign.Center) } }

五、异步写法(Promise 方式,项目主流)

除了putSync/getSync同步 API,官方推荐异步 API 避免阻塞 UI 线程:

ets

async function asyncOpt(context: common.UIAbilityContext) { let prefer = await preferences.getPreferences(context, "setting") // 异步存 await prefer.put("nightMode", true) // 异步读 let res = await prefer.get("nightMode", false) console.info("夜间模式:" + res) await prefer.flush() }

六、综合实战:应用设置页持久化开关

结合之前 Toggle 开关组件,实现开关状态永久保存,重启 APP 状态不变

ets

import preferences from '@ohos.data.preferences' import common from '@ohos.app.ability.common' @Component struct getPreferTool { static async getPre(context: common.UIAbilityContext, name: string) { return await preferences.getPreferences(context, name) } } @Entry @Component struct SettingStorePage { @State nightOpen: boolean = false @State notifyOpen: boolean = false context = getContext(this) as common.UIAbilityContext aboutToAppear() { // 页面加载读取本地存储 this.loadSetting() } // 读取配置 async loadSetting() { let pre = await getPreferTool.getPre(this.context, "app_setting") this.nightOpen = await pre.get("nightMode", false) this.notifyOpen = await pre.get("notify", true) } // 保存配置 async saveSetting() { let pre = await getPreferTool.getPre(this.context, "app_setting") await pre.put("nightMode", this.nightOpen) await pre.put("notify", this.notifyOpen) await pre.flush() } build() { Column({ space: 20 }) { Text("系统偏好设置").fontSize(22).fontWeight(FontWeight.Bold).margin({bottom:20}) Row() { Text("夜间模式").fontSize(18).layoutWeight(1) Toggle({ isOn: this.nightOpen }) .onChange((v: boolean) => { this.nightOpen = v this.saveSetting() }) } .width("100%") .padding(15) .backgroundColor("#fff") .borderRadius(8) Row() { Text("消息推送").fontSize(18).layoutWeight(1) Toggle({ isOn: this.notifyOpen }) .onChange((v: boolean) => { this.notifyOpen = v this.saveSetting() }) } .width("100%") .padding(15) .backgroundColor("#fff") .borderRadius(8) } .width("100%") .height("100%") .padding(20) .backgroundColor("#f5f5f5") } }

效果:修改开关后自动落地本地,关闭应用再次打开,开关状态和上次一致。

七、开发使用规范与注意事项

  1. 适用场景
  • ✅ 小型配置、登录标记、开关状态、用户简单信息
  • ❌ 大批量数据、复杂结构化数据(改用关系型数据库 RDB)
  1. flush () 必写:所有修改操作后必须执行 flush,否则数据仅存在内存,卸载 / 重启丢失;
  2. 文件名规范:按业务拆分文件,用户数据 user.xml、配置 setting.xml,不要全部塞进同一个文件;
  3. 默认值:get 时必须设置兜底默认值,防止 key 不存在返回 undefined 导致页面报错。
http://www.jsqmd.com/news/958862/

相关文章:

  • isUpMap:实时监控80多个热门互联网服务状态,一键掌握运行情况!
  • 2026年GEO上游原厂选型必看!十大靠谱GEO原厂全维度评测推荐+科学避坑指南 - 玖叁鹿
  • 实战指南:在快马平台部署一个基于langgraph的智能客服工单路由系统
  • 希尔伯特空间投影算子原理与机器学习应用
  • 保姆级教程:用维特智能USB-CAN模块给TX2开发板“嫁接”CAN总线,驱动大疆M3508电机
  • 2026 上半年高危 CVE 漏洞全景速览:1-4 月 TOP 20,你的系统中了几个?
  • 2026长沙配眼镜推荐去哪家,五家店验光售后哪家更靠谱 - 配眼镜新资讯
  • 【仅限首批内测用户开放】Veo 2运动增强模式(Beta 9.2)深度评测:亚像素级追踪精度如何实现?
  • 从ER图到建表:手把手教你设计一个完整的‘旅行社管理系统’数据库(MySQL版)
  • 别再手动写BPMN了!用Flowable流程设计器5分钟搞定一个报销审批流程图
  • 论文投稿救星:Word公式一键转MathType保姆级教程(附omml2mml.xsl报错终极解法)
  • 手把手教你给嵌入式Linux板子装上5G“翅膀”:移远RM500Q模块USB驱动移植保姆级教程
  • 告别BigDecimal的繁琐:用Hutool的NumberUtil搞定Java商业计算(含金额处理避坑指南)
  • 别再到处找资源了!D8(YT88)加密狗全套开发工具保姆级安装与配置指南
  • PyAEDT:5步掌握Ansys自动化仿真的终极指南
  • 从FIRST/FOLLOW集到预测分析表:图解LL(1)文法分析全过程(附C++核心算法)
  • LabelImg安装后打不开?5个常见报错排查与修复指南(Windows版)
  • gprMax3.0建模避坑指南:自定义几何形状时,HDF5文件与材料属性文件必须注意的3个细节
  • 实战项目架构优化:基于快马AI的代码依赖图分析与重构指南
  • 2026年成都弱电布线施工服务商TOP4推荐:成都小区监控安装、成都工厂安装监控、成都布线、成都无线网络布线、成都监控安装公司选择指南 - 优质品牌商家
  • 别再只会画流程图了!Flowable设计器里任务监听器和多实例的高级玩法详解
  • 告别Transformer的平方级计算:用两个线性层实现External Attention(EA)的保姆级解读
  • 告别重复劳动,用快马ai一键生成自动化数据分析周报脚本
  • 3分钟解锁Windows安卓应用安装:告别臃肿模拟器的终极方案
  • 手把手教你用矢量网络分析仪(VNA)测天线:从S11曲线到判断VSWR是否≤2的完整实操
  • 微信小程序计算机毕设之基于springboot+微信小程序的母猪生猪养殖信息化管理系统基于微信小程序生猪养殖信息化管理系统(完整前后端代码+说明文档+LW,调试定制等)
  • 告别AirDrop:在Linux上用wpa_supplicant和wpa_cli手搓一个P2P文件传输环境
  • 2026年近期天津诚信的蔡司蓝光三维扫描检测企业如何选择?楚天联合金属制品有限公司 - 2026年企业资讯
  • 5分钟快速部署:Brigadier帮你轻松获取Mac Boot Camp驱动
  • Blender 3MF插件终极指南:如何轻松实现3D打印格式完整导入导出