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

《个人头像上传》二、Preferences用户首选项使用指南

HarmonyOS @ohos.data.preferences 用户首选项完全指南:轻量级数据持久化实战

适用版本:HarmonyOS (API 23+)| DevEco Studio 6.1+
关键词:preferences、用户首选项、键值存储、数据持久化、getPreferencesSync


效果

一、前言

在移动应用开发中,我们经常需要保存一些轻量级数据——用户设置、主题偏好、登录状态标记等。这些数据不需要关系型数据库,但又不能每次启动都重新获取。

HarmonyOS 提供了@ohos.data.preferences(用户首选项)模块,为应用提供 Key-Value 键值型数据持久化能力。它的特点是:

  • 轻量级:适合存储配置信息、简单状态数据
  • 自动持久化:写入后自动保存到本地文件
  • 同步/异步双模式:灵活适配不同场景
  • 数据监听:支持监听数据变化事件

本文将全面讲解 Preferences API 的使用方法,并提供完整可运行的实例代码。


二、模块导入

import{preferences}from'@kit.ArkData';

首批接口从API version 9开始支持。


三、基本概念

3.1 数据存储模型

Preferences 采用Key-Value键值对存储:

限制
Key 最大长度1024 字节
Value 最大长度16MB

3.2 支持的 ValueType

typeValueType=number|string|boolean|Array<number>|Array<string>|Array<boolean>

不支持存储对象类型。如需存储对象,请先JSON.stringify()转为字符串。


四、获取 Preferences 实例

4.1 同步获取(推荐)

import{preferences}from'@kit.ArkData';import{common}from'@kit.AbilityKit';// 在 UIAbility 或组件中获取 Contextconstcontext=this.getUIContext().getHostContext()ascommon.UIAbilityContext;// 同步获取 Preferences 实例conststore=preferences.getPreferencesSync(context,{name:'my_store'});

4.2 异步获取

// Promise 方式conststore=awaitpreferences.getPreferences(context,{name:'my_store'});// Callback 方式preferences.getPreferences(context,{name:'my_store'},(err,store)=>{if(err){console.error('Failed to get preferences:',err);return;}// 使用 store});

4.3 关键区别

方法返回值适用场景
getPreferencesSyncPreferences启动时初始化,不阻塞UI
getPreferencesPromise<Preferences>需要异步等待的场景

注意:同一个name在同一应用内会返回同一个缓存实例,不会重复创建文件。


五、CRUD 操作详解

5.1 写入数据(put)

// 同步写入store.putSync('username','张三');store.putSync('age',25);store.putSync('isVip',true);store.putSync('scores',[98,85,92]);// 数组也支持// 异步写入awaitstore.put('username','张三');awaitstore.put('age',25);

重要put只写入内存缓存,必须调用flush才能持久化到磁盘!

5.2 读取数据(get)

// 同步读取(第二个参数是默认值)constusername=store.getSync('username','')asstring;constage=store.getSync('age',0)asnumber;constisVip=store.getSync('isVip',false)asboolean;// 异步读取constusername=awaitstore.get('username','')asstring;

get的第二个参数是默认值,当 key 不存在时返回该值。

5.3 检查 Key 是否存在(has)

// 同步检查constexists=store.hasSync('username');// 异步检查constexists=awaitstore.has('username');

5.4 删除数据(delete)

// 同步删除store.deleteSync('username');// 异步删除awaitstore.delete('username');

5.5 刷盘持久化(flush)

// 同步刷盘store.flushSync();// 异步刷盘awaitstore.flush();

最佳实践:批量写入后统一调用一次flush,避免频繁磁盘IO。

5.6 清空所有数据(clear)

// 同步清空store.clearSync();// 异步清空awaitstore.clear();

5.7 获取全部数据(getAll)

// 同步获取constallData=store.getAllSync()asRecord<string,preferences.ValueType>;// 异步获取constallData=awaitstore.getAll()asRecord<string,preferences.ValueType>;

六、数据变化监听

6.1 监听数据变化

// ✅ 推荐:监听 change 事件(API 9+,回调参数为变化的 key)constonChange=(key:string)=>{console.log(`Key "${key}" changed`);};store.on('change',onChange);// 监听 multiProcessChange 事件(API 10+,多进程场景)constonMultiProcessChange=(key:string)=>{console.log(`Multi-process: Key "${key}" changed`);};store.on('multiProcessChange',onMultiProcessChange);

⚠️ 注意dataChange事件(API 12+)的签名要求传入keys: string[]数组参数,回调返回Record<string, ValueType>,而非简单的无参回调。不要误用store.on('dataChange', () => {}),这会导致编译错误。

// ⚠️ dataChange 需要传入监听的 key 数组store.on('dataChange',['username','theme'],(data:Record<string,preferences.ValueType>)=>{console.log('Changed data:',JSON.stringify(data));});

6.2 取消监听

store.off('change',onChange);store.off('multiProcessChange',onMultiProcessChange);

七、完整实战实例:用户设置持久化

以下是一个完整的用户设置页面,演示 Preferences 的综合应用:

import{preferences}from'@kit.ArkData';import{common}from'@kit.AbilityKit';import{hilog}from'@kit.PerformanceAnalysisKit';constTAG='PreferencesDemo';/** * 用户设置管理器 */classSettingsManager{privatestore:preferences.Preferences|null=null;init(context:common.UIAbilityContext):void{this.store=preferences.getPreferencesSync(context,{name:'app_settings'});}// 保存用户设置saveSettings(nickname:string,themeMode:string,fontSize:number):void{if(!this.store)return;this.store.putSync('nickname',nickname);this.store.putSync('themeMode',themeMode);this.store.putSync('fontSize',fontSize);this.store.putSync('updateTime',Date.now().toString());this.store.flushSync();}// 加载用户设置loadSettings():{nickname:string;themeMode:string;fontSize:number}{if(!this.store){return{nickname:'默认用户',themeMode:'light',fontSize:16};}return{nickname:this.store.getSync('nickname','默认用户')asstring,themeMode:this.store.getSync('themeMode','light')asstring,fontSize:this.store.getSync('fontSize',16)asnumber};}// 清除所有设置clearAll():void{if(!this.store)return;this.store.clearSync();this.store.flushSync();}}@Entry@Componentstruct PreferencesDemo{@Statenickname:string='';@StatethemeMode:string='light';@StatefontSize:number=16;@StatestatusMessage:string='';privatesettingsMgr:SettingsManager=newSettingsManager();aboutToAppear():void{constcontext=this.getUIContext().getHostContext()ascommon.UIAbilityContext;if(context){this.settingsMgr.init(context);constsaved=this.settingsMgr.loadSettings();this.nickname=saved.nickname;this.themeMode=saved.themeMode;this.fontSize=saved.fontSize;}}build(){Column({space:16}){Text('用户设置').fontSize(22).fontWeight(FontWeight.Bold).margin({top:40});// 昵称输入Row(){Text('昵称:').width(80);TextInput({text:this.nickname,placeholder:'请输入昵称'}).layoutWeight(1).onChange((value:string)=>{this.nickname=value;});}.width('90%');// 主题选择Row(){Text('主题:').width(80);Radio({value:'light',group:'theme'}).checked(this.themeMode==='light').onChange((isChecked:boolean)=>{if(isChecked)this.themeMode='light';});Text('浅色').margin({right:16});Radio({value:'dark',group:'theme'}).checked(this.themeMode==='dark').onChange((isChecked:boolean)=>{if(isChecked)this.themeMode='dark';});Text('深色');}.width('90%');// 字体大小Row(){Text('字号:').width(80);Slider({value:this.fontSize,min:12,max:24,step:1}).layoutWeight(1).onChange((value:number)=>{this.fontSize=value;});Text(`${this.fontSize}px`).width(50);}.width('90%');// 保存按钮Button('保存设置').width('70%').height(44).onClick(()=>{this.settingsMgr.saveSettings(this.nickname,this.themeMode,this.fontSize);this.statusMessage='✓ 设置已保存';});// 清除按钮Button('恢复默认').width('70%').height(44).fontColor('#FF4444').backgroundColor('#FFF0F0').onClick(()=>{this.settingsMgr.clearAll();this.nickname='默认用户';this.themeMode='light';this.fontSize=16;this.statusMessage='✓ 已恢复默认设置';});// 状态提示if(this.statusMessage){Text(this.statusMessage).fontSize(14).fontColor('#4CAF50').margin({top:10});}}.width('100%').height('100%');}}

八、同步 vs 异步 API 选择策略

场景推荐方式原因
应用启动初始化getPreferencesSync快速获取实例,不影响启动速度
页面加载时读取配置getSync数据量小,同步读取更简单
保存用户设置putSync+flushSync确保立即持久化
后台批量数据写入put+flush(async)避免阻塞主线程
大体积数据写入put+flush(async)16MB上限内的大数据异步更安全

九、常见问题与最佳实践

Q1:Preferences 适合存什么数据?

适合:用户昵称、主题模式、字体大小、登录标记、简单配置项。

不适合:大量结构化数据(用关系型数据库 RDB)、二进制文件(用文件IO)、敏感信息(用加密存储)。

Q2:put 后必须 flush 吗?

是的put只修改内存中的值,不调用flush的话,应用重启后数据会丢失。

Q3:多进程可以共用一个 Preferences 吗?

不推荐。Preferences 无法保证进程并发安全。多进程场景请使用on('multiProcessChange')监听,或改用 RDB 数据库。

Q4:如何存储对象?

Preferences 不直接支持对象,需要序列化:

// 存储constuserObj={name:'张三',age:25};store.putSync('user',JSON.stringify(userObj));store.flushSync();// 读取constraw=store.getSync('user','')asstring;constuserObj=JSON.parse(raw)as{name:string;age:number};

Q5:如何删除 Preferences 文件?

// 删除首选项文件awaitpreferences.deletePreferences(context,{name:'my_store'});// 从缓存移除实例preferences.removePreferencesFromCacheSync(context,{name:'my_store'});

十、API 版本演进

API版本新增能力
9基础 CRUD、getPreferences、flush
10getPreferencesSync、getSync、putSync、flushSync、clearSync、hasSync
10multiProcessChange 监听
12dataChange 事件监听
14flushSync 同步刷盘
18StorageType 存储类型、isStorageTypeSupported

十一、总结

@ohos.data.preferences是 HarmonyOS 中轻量级数据持久化的首选方案。核心要点:

  1. getPreferencesSync获取实例,简单直接
  2. putSync + flushSync组合完成同步写入和持久化
  3. getSync读取数据,第二参数为默认值
  4. JSON.stringify序列化对象后再存储
  5. on(‘change’)监听数据变化(注意dataChange需要传入 keys 数组)
  6. 不适用于大数据量或多进程并发场景
http://www.gsyq.cn/news/1584679.html

相关文章:

  • TVA在机电产品视觉检测的创新应用(11)
  • 华为OD机试真题-预测新能源发电量(C/C++/Py/Java/Js/Go)
  • MacBook的实用小技巧
  • 高股息投资笔记-股票的人性2
  • 2 建立连接
  • LIVE项目解析:基于图像先验与时间一致性的AI视频编辑技术
  • 研发与业务协同工具怎么选?2026 主流团队云存储架构深度横评与避坑指南
  • [崛起]大国纪录片系列合集
  • 极小超曲面与Yau猜想:对称流形中的无限存在性定理
  • 2026新能源下乡155款车型全拆解:从625亿国补到铁锂涨价,全产业链机会地图
  • 百考通AI,论文降重与去AI痕迹,更安心,让数据为你说话
  • 东南亚多人手游区域 CDN 调优实战:新加坡、曼谷本地边缘节点降低联机延迟、过滤 UDP 异常流量
  • 视觉语言模型中的熵梯度证据定位技术解析
  • 基于通路交互图与GNN的多组学癌症转移预测模型构建指南
  • LLM提示词工程2.0:从Prompt到Prompt DSL的范式演进2026
  • RAP 里的 managed 与 unmanaged,别把它们理解成自动档和手动档那么简单
  • Linux环境下部署Zookeeper3.9.5(最新版)集群部署
  • 基于MobileNetV3的轻量化人脸年龄估计模型构建与移动端部署实战
  • 【学习心得 ● 运维】nginx 常用命令(烦人的Nginx)
  • DOSE:基于现成模型的多模态LLM训练数据筛选实战指南
  • DNA动力学可视化:深度学习与生物物理信息融合的ViDa框架解析
  • 大语言模型参数恢复的数学框架与实现
  • 北京离婚财产分割律师联系方式推荐 资深律师曹子燕执业服务指南
  • temu商家端加密分析
  • CQR与马氏距离:为VLA机器人构建不确定性感知的安全决策框架
  • 2026年LLM API智能路由:多模型网关的工程选型与实战
  • 基于深度强化学习的多目标SAR无人机智能路径规划实战解析
  • 图卷积网络与约束感知学习在动态微电网恢复中的应用
  • 基于Stackelberg博弈与可排空性护栏的GPU云平台定价与扩缩容策略
  • 硅光子打破功耗墙:AI训练能耗降低60%,台积电2026年量产CPO