Flutter 应用中远程数据本地存储的最优策略是什么?
Flutter 低频更新JSON数据持久化实现方案
针对你提到的每周更新一次、需转Map使用的大量JSON数据缓存需求,优先选择轻量、适配性高的方案,具体实现如下:
首选方案:shared_preferences + 过期校验
这是最适配你需求的方案,由Flutter官方维护,跨平台兼容性强,操作逻辑简单:
- 依赖引入:在
pubspec.yaml中添加依赖shared_preferences: ^2.2.2,执行flutter pub get完成安装 - 核心逻辑:同时存储JSON序列化字符串和缓存写入时间戳,每次启动先校验缓存有效性,未过期直接读取本地数据,过期再发起网络请求更新缓存
- 参考实现代码:
import 'dart:convert'; import 'package:shared_preferences/shared_preferences.dart'; class RemoteJsonCache { // 缓存key常量 static const String _dataKey = 'remote_json_content'; static const String _timeKey = 'remote_json_cache_timestamp'; static const int _validityPeriod = 7 * 24 * 60 * 60 * 1000; // 7天有效期,单位毫秒 // 读取缓存数据 static Future<Map<String, dynamic>?> loadData() async { final sp = await SharedPreferences.getInstance(); final int? cacheTime = sp.getInt(_timeKey); final String? jsonContent = sp.getString(_dataKey); // 校验缓存是否存在且未过期 if (cacheTime != null && jsonContent != null) { final currentTime = DateTime.now().millisecondsSinceEpoch; if (currentTime - cacheTime < _validityPeriod) { return jsonDecode(jsonContent); } } return null; } // 写入新的缓存数据 static Future<void> saveData(Map<String, dynamic> data) async { final sp = await SharedPreferences.getInstance(); await sp.setString(_dataKey, jsonEncode(data)); await sp.setInt(_timeKey, DateTime.now().millisecondsSinceEpoch); } }
- 使用方式:启动应用时先调用
loadData(),返回非空直接使用,返回为空则发起网络请求拉取数据,拉取成功后调用saveData()存到本地即可。
备选方案:本地文件存储(单份JSON大于10MB时使用)
如果你的单份JSON数据超过10MB,shared_preferences在部分低端设备上可能存在读写性能损耗,此时换成文件存储即可:
- 依赖引入
path_provider: ^2.1.1,用于获取应用专属的文档存储目录 - 逻辑和上面一致,只是将JSON字符串写入单独的
.json文件,时间戳可以存在文件名里或者单独用shared_preferences存储,大文件读写性能更高,没有存储大小限制。
不推荐方案
- 不要使用SQLite等关系型数据库:你不需要复杂查询操作,只会徒增集成和维护成本
- 不要仅使用内存缓存:应用杀进程后缓存就会清空,达不到持久化的需求
补充注意点:如果服务端有提供数据版本号,可以把版本号也存在本地,校验优先级高于时间戳,可实现低于7天的强制更新需求
内容的提问来源于stack exchange,提问作者YU No
相关产品推荐
相关产品推荐

