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

Flutter Hive以DateTime为键存储NotesModel对象列表报错如何处理

问题原因
  • Box泛型定义错误:Hive不支持直接将自定义对象的列表作为Box的泛型值类型,你注册的只有NotesModel的序列化适配器,并没有注册List<NotesModel>的适配器,Hive无法识别该类型,因此抛出未知类型错误。
  • TypeAdapter代码存在多处低级错误:
    • read方法返回值错误写为TimeBlockModel,和适配器绑定的NotesModel不匹配
    • ==运算符重载中判断类型错误写为TimeBlockModelAdapter,会导致适配器匹配失效
    • write方法首行writeByte(4)参数错误,你只有2个字段(索引0、1),需要传入2而非4,否则序列化时会生成冗余字段,读取时报错
  • 可选隐藏问题:如果你直接使用DateTime.now()作为存储键,Hive的键仅支持int和String类型,直接传入DateTime会导致类型异常。
解决方案
  1. 修正Box相关代码,去掉List<NotesModel>泛型约束:
// 自定义Box获取类
class NotedBox {
  static Box getNotedBox() {
    return Hive.box("Notes");
  }
}

// main.dart中打开Box的代码
await Hive.openBox("Notes");
  1. 修正NotesModelAdapter的全部错误:
class NotesModelAdapter extends TypeAdapter<NotesModel> {
  @override
  final int typeId = 1;

  @override
  NotesModel read(BinaryReader reader) {
    final numOfFields = reader.readByte();
    final fields = <int, dynamic>{
      for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
    };
    return NotesModel(
      title: fields[0] as String,
      description: fields[1] as String,
    );
  }

  @override
  void write(BinaryWriter writer, NotesModel obj) {
    writer
      ..writeByte(2) // 字段数量改为2
      ..writeByte(0)
      ..write(obj.title)
      ..writeByte(1)
      ..write(obj.description);
  }

  @override
  int get hashCode => typeId.hashCode;

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is NotesModelAdapter && // 改为当前适配器类型
          runtimeType == other.runtimeType &&
          typeId == other.typeId;
}
  1. 调整存储/读取逻辑,转换DateTime类型为合法键,读取时手动转换列表类型:
// 存储示例
final box = NotedBox.getNotedBox();
// 转为毫秒时间戳作为int类型键
final saveKey = DateTime.now().millisecondsSinceEpoch;
final notesList = [
  NotesModel(title: "笔记1", description: "笔记1描述"),
  NotesModel(title: "笔记2", description: "笔记2描述"),
];
await box.put(saveKey, notesList);

// 读取示例
final dynamic listData = box.get(saveKey);
if (listData is List) {
  final List<NotesModel> typedNotesList = listData.cast<NotesModel>();
  // 后续业务逻辑
}
  1. 操作完成后先卸载应用清除本地缓存的旧Box数据,再重新运行测试,避免旧数据结构冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 23:18:02