Flutter Hive存储API数据时首个地址pointOfServices为空问题排查
问题:Flutter中Hive存储配送地址时首个地址的pointOfServices为NULL
API返回的配送地址数据结构如下:
{"deliveryAddresses": [{"deliveryAddressNo": "1130119","deliveryAddressName": "AIRCRAFT MOVEMENTS 2169 (EAA)","pointOfServices": [{"deliveryAddressNo": "1130119","pointOfServiceNo": "1","pointOfServiceName": "HT54505","pointOfServiceDescription": ""},{"deliveryAddressNo": "1130119","pointOfServiceNo": "2","pointOfServiceName": "WASH BAY","pointOfServiceDescription": ""}]},{"deliveryAddressNo": "1130147","deliveryAddressName": "TESCO - 6144 - HARROW APOLLO","pointOfServices": [{"deliveryAddressNo": "1130147","pointOfServiceNo": "1","pointOfServiceName": "ACTE711092","pointOfServiceDescription": ""}]}]}
将数据写入Hive Box后,首个地址的2个pointOfServices显示为NULL,但第二个地址的pointOfServices写入正常。相关代码如下:
配送地址Model代码
List<Order> orderListFromJson(String val) => List<Order>.from(json.decode(val)['deliveryAddresses'].map((val) => Order.orderInfofromJson(val))); @HiveType(typeId: 0) class Order extends HiveObject { @HiveField(0) String? deliveryAddressNo; @HiveField(1) String? deliveryAddressName; @HiveField(2) List<PointOfServices>? pointOfServices; Order({this.deliveryAddressNo, this.deliveryAddressName, this.pointOfServices}); factory Order.orderInfofromJson(Map<String, dynamic> deliveryAddresses) => Order( deliveryAddressNo: deliveryAddresses['deliveryAddressNo'], deliveryAddressName: deliveryAddresses['deliveryAddressName'], pointOfServices: List<PointOfServices>.from( deliveryAddresses['pointOfServices'].map((pos) => PointOfServices.fromJson(pos)))); }
服务点Model代码
List<PointOfServices> posListFromJson(String val) => List<PointOfServices>.from(json.decode(val)['pointOfServices'].map((val) => PointOfServices.fromJson(val))); @HiveType(typeId: 1) class PointOfServices { @HiveField(7) String? deliveryAddressNo; @HiveField(8) String? pointOfServiceNo; @HiveField(9) String? pointOfServiceName; @HiveField(10) String? pointOfServiceDescription; PointOfServices({this.deliveryAddressNo,this.pointOfServiceNo,this.pointOfServiceName,this.pointOfServiceDescription}); factory PointOfServices.fromJson(Map<String, dynamic> pointOfServices) => PointOfServices( deliveryAddressNo: pointOfServices['deliveryAddressNo'], pointOfServiceNo: pointOfServices['pointOfServiceNo'], pointOfServiceName: pointOfServices['pointOfServiceName'], pointOfServiceDescription: pointOfServices['pointOfServiceDescription']); }
存储数据代码
if (!Hive.isBoxOpen(orderInfoBox)) { _orderInfo = await Hive.openBox<Order>('orderInfo_db'); _orderInfo.clear(); var result = await OrderNetwork().get(); var resultBody = await json.decode(json.encode(result.body)); List<Order> orderList = List<Order>.empty(growable: true); orderList.addAll(orderListFromJson(resultBody)); _orderInfo.addAll(orderList); }
排查与修复
问题根源
Hive要求每个@HiveField的编号必须从0开始连续递增,不能跳号。PointOfServices类直接使用了7、8、9、10这类跳号的字段ID,导致Hive序列化/反序列化时出现异常,部分数据无法正确存储。第二个地址的pointOfServices看似正常属于偶然情况,并非稳定正确的表现。
修复步骤
- 修正PointOfServices的字段ID
将PointOfServices类的@HiveField编号改为从0开始连续分配:
@HiveType(typeId: 1) class PointOfServices { @HiveField(0) String? deliveryAddressNo; @HiveField(1) String? pointOfServiceNo; @HiveField(2) String? pointOfServiceName; @HiveField(3) String? pointOfServiceDescription; // 构造函数和fromJson方法保持不变 }
- 确认适配器已注册
在应用初始化阶段,必须注册两个类的Hive适配器,示例代码:
void main() async { await Hive.initFlutter(); Hive.registerAdapter(OrderAdapter()); Hive.registerAdapter(PointOfServicesAdapter()); runApp(MyApp()); }
- 清理旧存储(建议)
由于之前错误的字段ID可能导致存储数据损坏,建议删除旧的Hive Box文件后重新运行,避免缓存干扰。
内容的提问来源于stack exchange,提问作者Dean Ball
相关产品推荐
相关产品推荐

