Flutter中如何将Map<String, List<object>>存储到SharedPreferences
解决方案
报错原因说明
你遇到的两个报错均是序列化逻辑缺失导致的:
- 直接调用
json.encode()失败:Dart 内置JSON序列化仅支持num、String、bool、List、Map、null这类基础类型,自定义类MyObj没有对应的序列化规则时,就会抛出对象转可编码结构失败的错误。- 调用
json.decode()格式错误:你之前存入的字符串大概率是直接调用Map的toString()生成的,这类字符串包含Instance of 'MyObj'这类非标准JSON格式的内容,解码时自然无法识别。
方案1:手动处理无需额外第三方包
步骤1:给MyObj添加序列化/反序列化方法
给自定义类补充toJson(转可序列化Map)和fromJson(从Map转回实例)方法,示例代码如下:
class MyObj { // 替换为你实际的类字段 final String id; final int count; MyObj({required this.id, required this.count}); /// 转可序列化的Map结构 Map<String, dynamic> toJson() { return { 'id': id, 'count': count, // 补充所有你需要持久化的字段 }; } /// 从Map结构生成MyObj实例 factory MyObj.fromJson(Map<String, dynamic> json) { return MyObj( id: json['id'] as String, count: json['count'] as int, // 对应上面toJson的所有字段 ); } }
步骤2:存储数据
先把整个Map<String, List<MyObj>>转成全基础类型的可序列化结构,再编码为JSON字符串存入SharedPreferences:
import 'dart:convert'; import 'package:shared_preferences/shared_preferences.dart'; // 你的源数据 Map<String, List<MyObj>> originalData = { "ExampleString": [MyObj(id: "1", count: 2), MyObj(id: "2", count: 3)], "ExampleString2": [MyObj(id: "3", count: 5)] }; Future<void> saveData() async { final prefs = await SharedPreferences.getInstance(); // 转换为可序列化的结构 final serializableData = originalData.map((key, value) => MapEntry( key, value.map((obj) => obj.toJson()).toList(), )); // 编码为JSON字符串存储 await prefs.setString('my_custom_data', json.encode(serializableData)); }
步骤3:读取数据
读取JSON字符串后解码,再逐字段转换回Map<String, List<MyObj>>结构:
Future<Map<String, List<MyObj>>?> loadData() async { final prefs = await SharedPreferences.getInstance(); final jsonStr = prefs.getString('my_custom_data'); if (jsonStr == null) return null; // 解码为基础类型结构 final decodedMap = json.decode(jsonStr) as Map<String, dynamic>; // 转换为目标结构 return decodedMap.map((key, value) => MapEntry( key, (value as List<dynamic>).map((item) => MyObj.fromJson(item as Map<String, dynamic>)).toList(), )); }
方案2:使用第三方包简化流程
如果不想手动维护序列化逻辑,可以选择以下成熟的第三方库:
json_serializable:Dart官方推荐的序列化工具,配合build_runner可自动生成toJson/fromJson代码,无需手动编写,避免手写出错。hive:轻量级NoSQL本地存储库,性能优于SharedPreferences,支持直接存储自定义类型,只需给自定义类注册适配逻辑即可,无需手动转JSON字符串。get_storage:基于SharedPreferences封装的轻量存储库,对序列化逻辑做了封装,使用更简单,同样需要先给自定义类实现序列化规则。
内容的提问来源于stack exchange,提问作者user16712640
相关产品推荐
相关产品推荐

