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会导致类型异常。
解决方案
- 修正Box相关代码,去掉
List<NotesModel>泛型约束:
// 自定义Box获取类 class NotedBox { static Box getNotedBox() { return Hive.box("Notes"); } } // main.dart中打开Box的代码 await Hive.openBox("Notes");
- 修正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; }
- 调整存储/读取逻辑,转换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>(); // 后续业务逻辑 }
- 操作完成后先卸载应用清除本地缓存的旧Box数据,再重新运行测试,避免旧数据结构冲突。
内容的提问来源于stack exchange,提问作者Ayush Rawat
相关产品推荐
相关产品推荐

