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

Flutter Hive重启报错:List<dynamic>无法转为List<Bookingday>?

问题原因及解决方案

核心原因

Hive 对泛型列表的序列化支持有限:同一会话内,列表中的 Bookingday 对象仍在内存中,类型信息完整,所以读取时能直接识别;但重启APP后,Hive从磁盘读取数据时,会把存储的列表解析为 List<dynamic>,无法自动转换为 List<Bookingday>——因为Hive的类型适配器(TypeAdapter)是针对单个自定义对象设计的,而非列表本身。

解决方案

方案1:用包装类封装列表(推荐)

创建一个包含 List<Bookingday> 的包装类,给该类生成Hive类型适配器,让Hive能正确序列化/反序列化整个列表结构。

  1. 定义包装类 BookingWeek 并添加Hive注解
import 'package:hive/hive.dart';
import 'bookingday.dart';

part 'booking_week.g.dart';

@HiveType(typeId: 1) // 确保typeId不与其他类冲突
class BookingWeek {
  @HiveField(0)
  List<Bookingday> days;

  BookingWeek({required this.days});
}
  1. 确保 Bookingday 已配置Hive注解和适配器
import 'package:hive/hive.dart';

part 'bookingday.g.dart';

@HiveType(typeId: 0)
class Bookingday {
  @HiveField(0)
  DateTime day;
  @HiveField(1)
  bool parkingSlotReserved;
  @HiveField(2)
  int capacityCounter;
  @HiveField(3)
  int maxCapacity;

  Bookingday({
    required this.day,
    required this.parkingSlotReserved,
    required this.capacityCounter,
    required this.maxCapacity,
  });
}
  1. 生成适配器并注册
    运行命令生成适配器:
flutter packages pub run build_runner build

在 main.dart 中注册适配器并打开Box:

void main() async {
  await Hive.initFlutter();
  Hive.registerAdapter(BookingdayAdapter());
  Hive.registerAdapter(BookingWeekAdapter());
  await Hive.openBox<BookingWeek>(bookingDayBoxName);
  runApp(MyApp());
}
  1. 修改DAO的读写逻辑
Box<BookingWeek> box = Hive.box<BookingWeek>(bookingDayBoxName);

List<Bookingday> getStoredWeek(DateTime firstJan, DateTime date) {
  String key = getCalenderWeek(firstJan, date);
  try {
    BookingWeek? week = box.get(key);
    if (week != null) {
      bookingdays = week.days;
      return week.days;
    } else {
      List<DateTime> weekDates = getWeek(dateNow);
      return List.generate(
        weekDates.length,
        (index) => Bookingday(
          day: weekDates[index],
          parkingSlotReserved: false,
          capacityCounter: 0,
          maxCapacity: 4,
        ),
      );
    }
  } catch (e) {
    print(e);
  }
  return bookingdays;
}

// 存储方法也要对应修改
void saveWeek(DateTime firstJan, DateTime date, List<Bookingday> days) {
  String key = getCalenderWeek(firstJan, date);
  box.put(key, BookingWeek(days: days));
}

方案2:手动转换列表(应急用)

如果不想修改结构,可以在读取时手动将 List<dynamic> 转换为 List<Bookingday>,但这种方式风险较高(若数据损坏会抛出类型转换异常):

List<Bookingday>? bookList = (boxList.get(key) as List<dynamic>?)?.map((item) => item as Bookingday).toList();

内容的提问来源于stack exchange,提问作者Yusaku Goldbach

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 16:55:18