在日常 Flutter 开发中,经常会遇到需要存储用户偏好设置、登录状态、简单配置项等轻量级数据的场景。这类数据无需复杂的数据库结构,但要求读写高效、跨平台兼容且接入成本低。此前我尝试过手动封装原生存储逻辑(如 Android 的 SharedPreferences、iOS 的 NSUserDefaults),但存在代码冗余、多平台适配繁琐的问题。了解到 shared_preferences 是 Flutter 生态中专门解决这类问题的官方推荐插件,而 2.5.4 版本作为稳定版,不仅修复了旧版本的异步读写缺陷,还优化了多平台存储逻辑,因此专门深入学习该版本的使用方式,旨在掌握轻量级本地存储的标准化实现方案,提升项目中数据持久化的开发效率,同时规避因缓存、跨隔离区访问导致的数据一致性问题。
Flutter 结合 shared_preferences 2.5.4 实现本地轻量级数据存储
技术背景与需求分析
- 移动应用数据持久化的常见场景
- shared_preferences 的定位与适用场景(轻量级键值对存储)
- 对比其他本地存储方案(SQLite、Hive、文件存储)
shared_preferences 2.5.4 核心特性
- 支持数据类型:
int、double、bool、String、List<String> - 跨平台兼容性(iOS/Android/Web)
- 同步与异步操作差异说明
环境配置与依赖集成
- 在
pubspec.yaml中添加依赖:dependencies: shared_preferences: ^2.5.4 - 执行
flutter pub get - 导入库:
import 'package:shared_preferences/shared_preferences.dart';
基础操作实现
- 初始化 SharedPreferences 实例:
final prefs = await SharedPreferences.getInstance(); - 数据写入示例:
prefs.setInt('counter', 42); prefs.setString('username', 'FlutterUser'); - 数据读取示例:
int? counter = prefs.getInt('counter'); String? username = prefs.getString('username'); - 删除数据与清空存储:
prefs.remove('counter'); prefs.clear();
高级应用场景
- 监听数据变化:通过
Stream或ValueNotifier包装 - 复杂对象存储:JSON 序列化与反序列化(结合
dart:convert) - 安全增强:敏感数据加密建议(如结合
flutter_secure_storage)
性能优化与最佳实践
- 避免频繁调用
getInstance() - 批量写入使用
commit()替代set方法链 - 异常处理与空安全适配
常见问题排查
- 数据类型不匹配导致的读取失败
- Web 平台兼容性注意事项
- 调试技巧:查看原生平台存储文件位置
实战案例演示
- 用户偏好设置(主题、语言切换)
- 应用状态持久化(登录状态、历史记录)
- 离线缓存策略设计
版本迁移与升级指南
- 从旧版本迁移到 2.5.4 的改动点
- 废弃 API 替代方案
参考资料与扩展阅读
- 官方插件文档链接
- 社区推荐的最佳实践文章
- 相关开源项目案例
一、shared_preferences 2.5.4 核心特性与适配说明
1.1 版本核心更新
| 特性 / 优化点 | 具体说明 |
|---|---|
| API 稳定性提升 | 修复 2.3.x 版本中SharedPreferencesAsync异步读写的偶发阻塞问题 |
| 多平台适配完善 | 优化 Windows 端 AppData 目录读写权限,macOS 10.15 + 兼容性增强 |
| 缓存机制优化 | SharedPreferencesWithCache的缓存刷新逻辑更高效,减少多隔离区数据不一致 |
| 迁移工具完善 | 提供更健壮的旧版 API 向新版异步 API 迁移工具,降低数据丢失风险 |
1.2 平台存储位置与支持类型
(1)各平台存储路径
| 平台 | SharedPreferences(旧版) | SharedPreferencesAsync/WithCache(新版) |
|---|---|---|
| Android | 系统 SharedPreferences(xml 文件) | DataStore Preferences(默认)/SharedPreferences |
| iOS/macOS | NSUserDefaults | NSUserDefaults |
| Linux | XDG_DATA_HOME 目录下的键值文件 | XDG_DATA_HOME 目录下的键值文件 |
| Web | 浏览器 LocalStorage | 浏览器 LocalStorage |
| Windows | 系统漫游 AppData 目录 | 系统漫游 AppData 目录 |
(2)支持的数据类型
该版本仅支持以下基础数据类型,不支持自定义对象(需序列化后以 String 存储):int、double、bool、String、List<String>
二、核心 API 分类与使用场景
2.5.4 版本提供三类核心 API,适配不同的开发场景,开发者可根据性能、数据一致性需求选择:
| API 类型 | 核心特点 | 适用场景 | 性能 | 数据一致性 |
|---|---|---|---|---|
| SharedPreferences(旧版) | 带本地缓存,同步 get / 异步 set,未来将废弃 | 简单场景、低频次读写、无需跨隔离区访问 | 高 | 较低 |
| SharedPreferencesAsync | 无缓存,全异步读写,直接访问原生存储 | 多隔离区 / 多引擎实例、跨端数据同步场景 | 中 | 高 |
| SharedPreferencesWithCache | 带可控缓存,同步 get / 异步 set,可配置白名单 | 高频次读操作、需平衡性能与数据一致性场景 | 高 | 中 |
三、实操案例:不同 API 的使用方式
3.1 基础配置
首先在pubspec.yaml中引入依赖:
dependencies: flutter: sdk: flutter shared_preferences: 2.5.4 # 如需Android端指定SharedPreferences后端,需额外引入 # shared_preferences_android: ^2.2.03.2 旧版 SharedPreferences(兼容使用)
适合快速实现简单存储,注意该 API 未来将废弃,新工程建议使用新版:
import 'package:shared_preferences/shared_preferences.dart'; // 写入数据 Future<void> saveUserData() async { // 获取实例(异步) final SharedPreferences prefs = await SharedPreferences.getInstance(); // 写入不同类型数据 await prefs.setInt('user_age', 25); await prefs.setBool('is_login', true); await prefs.setString('user_name', 'FlutterDev'); await prefs.setStringList('hobbies', ['coding', 'reading', 'running']); } // 读取数据 Future<void> readUserData() async { final SharedPreferences prefs = await SharedPreferences.getInstance(); // 同步读取,无数据返回null final int? age = prefs.getInt('user_age'); final bool? isLogin = prefs.getBool('is_login'); final String? name = prefs.getString('user_name'); final List<String>? hobbies = prefs.getStringList('hobbies'); print('用户名:$name,年龄:$age,是否登录:$isLogin'); } // 删除数据 Future<void> removeData() async { final SharedPreferences prefs = await SharedPreferences.getInstance(); await prefs.remove('user_age'); // 删除指定键 // await prefs.clear(); // 清空所有数据 }3.3 新版 SharedPreferencesAsync(推荐)
无缓存设计,保证数据一致性,适合多场景数据读写:
import 'package:shared_preferences/shared_preferences.dart'; // 初始化异步实例 final SharedPreferencesAsync asyncPrefs = SharedPreferencesAsync(); // 写入数据 Future<void> saveDataAsync() async { await asyncPrefs.setDouble('score', 98.5); await asyncPrefs.setString('token', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'); } // 读取数据 Future<void> readDataAsync() async { final double? score = await asyncPrefs.getDouble('score'); final String? token = await asyncPrefs.getString('token'); print('分数:$score,Token:$token'); } // 清空数据(指定白名单,仅删除白名单外数据) Future<void> clearDataAsync() async { await asyncPrefs.clear(allowList: {'token'}); // 保留token键 }3.4 SharedPreferencesWithCache(高性能读写)
带缓存的新版 API,适合高频读场景,可配置白名单限制可操作的键:
import 'package:shared_preferences/shared_preferences.dart'; // 创建带缓存的实例,指定白名单 Future<void> initCachePrefs() async { final SharedPreferencesWithCache prefsWithCache = await SharedPreferencesWithCache.create( cacheOptions: const SharedPreferencesWithCacheOptions( allowList: {'theme_mode', 'font_size'}, // 仅允许操作这两个键 ), ); // 写入数据 await prefsWithCache.setInt('font_size', 16); await prefsWithCache.setBool('theme_mode', true); // 同步读取缓存数据 final int? fontSize = prefsWithCache.getInt('font_size'); print('字体大小:$fontSize'); // 清空数据(白名单已配置,无需重复传) await prefsWithCache.clear(); }3.5 旧版迁移到新版 API
2.5.4 版本提供了便捷的迁移工具,确保旧版数据无缝迁移到新版异步 API:
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/util/legacy_to_async_migration_util.dart'; Future<void> migrateData() async { // 获取旧版实例 final SharedPreferences legacyPrefs = await SharedPreferences.getInstance(); // 执行迁移(仅首次执行,通过migrationCompletedKey标记) await migrateLegacySharedPreferencesToSharedPreferencesAsyncIfNecessary( legacySharedPreferencesInstance: legacyPrefs, sharedPreferencesAsyncOptions: const SharedPreferencesOptions(), migrationCompletedKey: 'migration_completed_2025', // 自定义标记键 ); }四、注意事项
- 数据安全性:该插件仅适用于非敏感数据存储(如用户偏好设置、简单配置),密码、token 等敏感数据需加密后再存储;
- 跨隔离区使用:若在多隔离区中使用带缓存的 API,需在读取前调用
reload()刷新缓存,避免数据不一致; - Android 后端选择:如需兼容原生 Android 的 SharedPreferences 数据,需通过
SharedPreferencesAsyncAndroidOptions指定后端类型; - 数据量限制:适合存储 KB 级别的小数据,大量数据建议使用 Hive、SQFlite 等数据库。
五、总结
shared_preferences 2.5.4 版本通过三类差异化 API,满足了 Flutter 开发者在不同场景下的本地轻量级存储需求。新版异步 API(SharedPreferencesAsync/WithCache)解决了旧版缓存导致的数据一致性问题,同时保持了易用性;旧版 API 则可作为过渡方案。开发者可根据项目的性能、一致性需求选择合适的 API,结合平台特性做好适配,高效实现本地数据持久化。
欢迎大家加入[开源鸿蒙跨平台开发者社区](https://openharmonycrossplatform.csdn.net),一起共建开源鸿蒙跨平台生态。