4、Preferences进阶:数据持久化与同步、监听数据变化(on/off)、批量操作、异常处理
4.1 数据持久化:不只是存进去那么简单
Preferences 说白了就是个轻量级数据库。但很多新手容易犯一个错——存完数据以为万事大吉,结果应用一重启,数据全丢了。
为什么会这样?因为 Preferences 的数据默认是缓存在内存里的。你调用 put 方法,只是写进了内存。要真正持久化到磁盘,必须调用 flush 或者 flushSync。
核心原则:每次写入后,记得调用 flush。否则数据可能丢失。
我习惯这样写:
// 写入数据
preferences.put('userName', '张三');
// 立即持久化
preferences.flush();
你可能会问:每次都 flush,性能会不会有问题?其实 Preferences 内部做了优化。多次 put 后只调用一次 flush,它会批量写入。我个人建议在关键操作后调用,比如用户退出页面时。
4.2 监听数据变化:on/off 的妙用
我在项目中遇到过这样一个场景:用户修改了昵称,其他页面需要实时更新。如果每个页面都去轮询读取,太傻了。Preferences 提供了 on 和 off 方法,专门解决这个问题。
用法很简单:
// 注册监听
let callback = (key, value) => {
console.log(`键 ${key} 变更为 ${value}`);
};
preferences.on('change', callback);
// 取消监听
preferences.off('change', callback);
嗯,这里要注意:on 的回调函数必须和 off 的是同一个引用。如果你写成匿名函数,那就没法取消了。我曾经踩过这个坑,导致内存泄漏。
小技巧:在页面销毁时(比如 onPageHide 或 aboutToDisappear),记得调用 off 取消监听。否则页面虽然关了,回调还在跑。
4.3 批量操作:一次搞定多个键值
你想想看,如果一次要存 10 个配置项,写 10 次 put 再 10 次 flush,多累啊。Preferences 支持批量操作,效率高得多。
批量写入:
preferences.put('key1', 'value1');
preferences.put('key2', 'value2');
preferences.put('key3', 'value3');
// 一次性持久化
preferences.flush();
批量读取:
let keys = ['key1', 'key2', 'key3'];
let values = keys.map(key => preferences.get(key, 'default'));
说白了,就是先攒一波操作,最后统一提交。我一般在应用启动时批量读取配置,在退出时批量写入。这样既快又安全。
4.4 异常处理:别让崩溃毁了用户体验
Preferences 操作虽然简单,但也会出错。比如磁盘满了、文件损坏、权限不足。如果不做异常处理,应用直接闪退,用户会骂娘的。
我建议用 try-catch 包裹所有 Preferences 操作:
try {
await preferences.put('score', 100);
await preferences.flush();
} catch (err) {
console.error('Preferences 写入失败:', err);
// 可以提示用户,或者重试
}
读取时也要注意:
try {
let value = preferences.get('nonExistentKey', '默认值');
console.log(value); // 输出 '默认值'
} catch (err) {
console.error('读取失败:', err);
}
警告:不要忽略异常。我曾经在一个项目中偷懒没加 try-catch,结果用户手机存储空间不足时,应用直接崩溃。后来被测试小姐姐追着骂了一周。
4.5 知识体系总览
下面这张图帮你理清本章的核心逻辑:
4.6 实战建议
最后,给你几个我多年实战总结的建议:
- 不要存大对象:Preferences 适合存配置、状态等小数据。大对象请用数据库或文件。
- 键名要有规范:我习惯用
module_key的格式,比如user_name、setting_theme。避免冲突。 - 默认值要合理:读取时给个合理的默认值,别让用户看到 undefined 或 null。
- 监听要成对出现:有 on 必有 off,就像有借必有还。
好了,这一章的内容就这些。记住,Preferences 虽小,但用好了能省不少事。下次见。
公众号:蓝海资料掘金营,微信deep3321