Hive报错:‘ServerData’类型不是‘BluetoothEvent’类型的子类型
问题分析与解决方案
错误原因
出现type 'ServerData' is not a subtype of type 'BluetoothEvent' of 'obj'的核心原因有两点:
- Hive字段ID使用错误:
@HiveField的ID是类内唯一的,而非全局递增。你当前给不同类的字段使用了全局连续的ID,导致Hive序列化时混淆了类型映射。 - 潜在的Box误用:写入数据时可能误将
ServerData存入了专门存储BluetoothEvent的Box中,引发类型不匹配。
修复步骤
1. 修正所有类的@HiveField ID
每个类的字段ID从0开始重新编号,确保仅在当前类内唯一:
@HiveType(typeId: 0) class ServerData { @HiveField(0) final String roomId; @HiveField(1) final DateTime scanFinishedTime; @HiveField(2) final WifiAndBluetoothEvent wifiAndBluetoothEvent; ServerData({required this.roomId, required this.scanFinishedTime, required this.wifiAndBluetoothEvent}); }
@HiveType(typeId: 1) class WifiAndBluetoothEvent { @HiveField(0) List<WifiEvent> wifiEvents; @HiveField(1) List<BluetoothEvent> bluetoothEvents; WifiAndBluetoothEvent({required this.wifiEvents, required this.bluetoothEvents}); }
@HiveType(typeId: 2) class BluetoothEvent extends Equatable { @HiveField(0) final DateTime scanTime; @HiveField(1) final String name; @HiveField(2) final String macAddress; @HiveField(3) final BluetoothDeviceType? type; @HiveField(4) final int rssi; BluetoothEvent({required this.scanTime, required this.name, required this.macAddress, this.type, required this.rssi}); @override List<Object?> get props => [scanTime, name, macAddress, type, rssi]; }
@HiveType(typeId: 3) class WifiEvent extends Equatable { @HiveField(0) final String name; @HiveField(1) final String macAddress; @HiveField(2) final WiFiStandards standard; @HiveField(3) final int rssi; @HiveField(4) final WiFiChannelWidth? channelWidth; @HiveField(5) final int frequency; @HiveField(6) final DateTime timestamp; @HiveField(7) final DateTime receivedTime; WifiEvent({required this.name, required this.macAddress, required this.standard, required this.rssi, this.channelWidth, required this.frequency, required this.timestamp, required this.receivedTime}); @override List<Object?> get props => [name, macAddress, standard, rssi, channelWidth, frequency, timestamp, receivedTime]; }
2. 重新生成并注册所有适配器
执行Hive代码生成命令,确保适配器与修正后的实体类匹配:
flutter pub run build_runner build
然后确认所有适配器都被正确注册:
final adaptersToRegister = [ ServerDataAdapter(), WifiAndBluetoothEventAdapter(), BluetoothEventAdapter(), WifiEventAdapter(), ]; for (final adapter in adaptersToRegister) { Hive.registerAdapter(adapter); } final directory = await getApplicationDocumentsDirectory(); Hive.init(directory.path);
3. 检查Box的使用逻辑
写入ServerData时,确保使用对应类型的Box,避免与其他类型的存储混淆:
// 打开专门存储ServerData的Box final serverDataBox = await Hive.openBox<ServerData>('failed_server_data'); // 写入数据示例 final dataToSave = ServerData( roomId: '101', scanFinishedTime: DateTime.now(), wifiAndBluetoothEvent: WifiAndBluetoothEvent(wifiEvents: [], bluetoothEvents: []), ); await serverDataBox.add(dataToSave);
4. 清理旧存储(可选)
由于之前的字段ID错误可能导致存储数据损坏,建议清除旧的Hive存储后重新测试:
final directory = await getApplicationDocumentsDirectory(); await Hive.deleteBoxFromDisk('failed_server_data'); // 或删除整个Hive目录 await Hive.init(directory.path);
内容的提问来源于stack exchange,提问作者Baran
相关产品推荐
相关产品推荐

