在Hive Box中保存对象列表时类型推断异常问题
解决Hive存储嵌套对象列表的类型推断异常问题
问题场景
需要存储一组嵌套了DestinationResults(Hive对象)列表的CorrectionDestination对象,类定义如下:
CorrectionDestination类
@freezed class CorrectionDestination extends HiveObject with _$CorrectionDestination { CorrectionDestination._(); @HiveType(typeId: 4) factory CorrectionDestination({ @HiveField(0) required int stepId, @HiveField(1) required String stepTitle, @HiveField(2) required String stepType, @HiveField(3) required bool isCurrentStep, @HiveField(4) required int projectStepId, @HiveField(5) @JsonKey(defaultValue: []) required List<DestinationResults> results, }) = _CorrectionDestination; factory CorrectionDestination.fromJson(Map<String, dynamic> json) => _$CorrectionDestinationFromJson(json); }
DestinationResults类
@freezed class DestinationResults extends HiveObject with _$DestinationResults { DestinationResults._(); @HiveType(typeId: 5) factory DestinationResults({ @HiveField(0) required int stepResultId, @HiveField(1) required String stepResultTitle, }) = _DestinationResults; factory DestinationResults.fromJson(Map<String, dynamic> json) => _$DestinationResultsFromJson(json); }
问题现象
尝试通过带泛型的方式打开Box时出现类型推断异常:
final box = await Hive.openBox<List<CorrectionDestination>>('correctionDestinations');
但去掉泛型打开Box后,能通过打印获取到对象,但无法获得正确的类型约束:
final box = await Hive.openBox('correctionDestinations'); final availableDestinations = box.get(inspectionId); print(availableDestinations);
当前环境信息:
[✓] Flutter (Channel stable, 3.16.3, on macOS 14.2 23C64 darwin-arm64, locale en-UA) • Flutter version 3.16.3 on channel stable at /Users/lesha/fvm/versions/3.16.0 • Upstream repository https://github.com/flutter/flutter.git • Framework revision b0366e0a3f (5 weeks ago), 2023-12-05 19:46:39 -0800 • Engine revision 54a7145303 • Dart version 3.2.3 • DevTools version 2.28.4
解决方案
1. 手动转换类型(推荐)
Hive对泛型集合的类型推断支持有限,建议直接打开非泛型Box,在获取数据时手动完成类型转换:
final box = await Hive.openBox('correctionDestinations'); // 安全转换类型,处理空值 final List<CorrectionDestination>? availableDestinations = box.get(inspectionId) as List<CorrectionDestination>?; // 或添加空检查与类型校验 final data = box.get(inspectionId); if (data != null && data is List) { final List<CorrectionDestination> destinations = data.cast<CorrectionDestination>(); // 后续业务逻辑 }
2. 检查适配器注册顺序
确保两个类的适配器已在main函数中正确注册,嵌套类需优先注册:
void main() async { await Hive.initFlutter(); // 先注册嵌套的DestinationResults适配器 Hive.registerAdapter(DestinationResultsAdapter()); // 再注册CorrectionDestination适配器 Hive.registerAdapter(CorrectionDestinationAdapter()); runApp(const MyApp()); }
若适配器生成异常,执行flutter pub run build_runner build重新生成代码。
3. 用包装类实现强类型(可选)
如果需要严格的强类型约束,可以创建一个包装类来存储列表:
@HiveType(typeId: 6) class CorrectionDestinationList extends HiveObject { @HiveField(0) final List<CorrectionDestination> items; CorrectionDestinationList(this.items); }
注册该类的适配器后,即可用泛型方式操作Box:
// 注册适配器 Hive.registerAdapter(CorrectionDestinationListAdapter()); // 打开Box并存储数据 final box = await Hive.openBox<CorrectionDestinationList>('correctionDestinations'); await box.put(inspectionId, CorrectionDestinationList(destinationsList)); // 获取数据 final listWrapper = box.get(inspectionId); final List<CorrectionDestination> availableDestinations = listWrapper?.items ?? [];
内容的提问来源于stack exchange,提问作者maybemuf
相关产品推荐
相关产品推荐

