You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter SharedPreferences加载List报Null非List<Row>子类型异常

问题根因

报错type 'Null' is not a subtype of type 'List<Row>'的直接原因是代码预期获取非空的List<Row>类型值,实际拿到了null,对应到你的场景有四个常见触发点:

  • SharedPreferences的写入操作是异步的,如果调用写入方法时没有加await等待执行完成就触发热重启,数据根本没有落到本地存储,读取对应key时会直接返回null
  • Data类的fromJson构造方法对chatMessages字段做了非空强转,没有做null兼容,只要JSON中不存在该字段、或者字段值为null,强转逻辑就会抛出类型错误
  • SharedPreferences本身不支持直接存储自定义类型的List,如果你存的时候没有把对象先转成JSON字符串,直接传入List<Row>类型,存储逻辑会执行失败,读取时自然拿到null
  • 如果你用的Row是Flutter框架自带的Widget组件,它本身不支持JSON序列化,直接存储Widget实例必然会失败。
修复方案

按以下步骤调整代码即可解决:

  1. 修正写入逻辑,必须等待写入完成再执行后续操作,复杂对象先转成JSON字符串再存储
// 写入逻辑示例
final prefs = await SharedPreferences.getInstance();
// 先把数据对象转成JSON字符串,不要直接存自定义类/Widget实例
final String saveStr = jsonEncode(Data(
  chatMessages: yourMessageList, // 这里的列表元素要是可序列化的普通数据类,不能是Widget
).toJson());
// 必须加await等待写入完成,否则热重启/杀进程可能丢数据
await prefs.setString('data_cache_key', saveStr);
  1. 修正fromJson构造方法,给所有字段加空值兜底,不要直接做非空强转
factory Data.fromJson(Map<String, dynamic> json) {
  return Data(
    // 核心:字段先按可空类型解析,null时给空数组做兜底
    chatMessages: (json['chatMessages'] as List<dynamic>?)
        ?.map((item) => ChatMessageItem.fromJson(item as Map<String, dynamic>))
        .toList() 
        ?? const [],
    // 其余字段都按照相同逻辑加空兜底即可
  );
}

注意:聊天列表项要抽成普通数据类存储,渲染时再根据数据生成Row组件,不要直接把Row组件当数据存。

  1. 修正读取逻辑,兼容本地无缓存的场景
// 读取逻辑示例
final prefs = await SharedPreferences.getInstance();
Data cacheData;
final String? cacheStr = prefs.getString('data_cache_key');
if (cacheStr != null) {
  // 本地有缓存时再做反序列化
  cacheData = Data.fromJson(jsonDecode(cacheStr) as Map<String, dynamic>);
} else {
  // 无缓存时初始化空数据,避免null
  cacheData = Data(chatMessages: const []);
}

补充说明:热重启会重置Flutter应用的内存状态,但不会清空SharedPreferences的本地持久化文件,只要写入逻辑正确等await执行完成,热重启后是可以正常读到数据的。

验证方法

改完后按以下顺序验证即可:

  • 写入测试数据后,确认setString的异步方法执行完成,再触发热重启,检查列表加载是否正常
  • 手动清除应用数据/删除对应缓存key,冷启动应用,确认不会崩溃,正常显示空列表
  • 存入测试数据后杀掉应用进程重新打开,确认列表数据正常加载

内容的提问来源于stack exchange,提问作者CastoldiG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 19:15:28