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

Flutter+Hive报错:Box 'todo_box'已打开且类型不匹配

错误原因分析

这个错误的核心是同一个Hive Box被以两种不同类型打开:

  • 在main.dart中,你用无类型方式打开todo_box:await Hive.openBox('todo_box');,生成的是Box<dynamic>实例。
  • 但在list_screen.dart和add_todo_screen.dart中,你又以Box<Todo>类型获取同一个box:Hive.box<Todo>(HiveBoxes.todo)。
    Hive不允许同一个box同时存在不同类型的实例,因此触发了类型冲突错误。

另外还有两个次要问题会加剧异常:

  1. schedule.dart中嵌套了MaterialApp,导致上下文混乱,可能触发重复初始化逻辑。
  2. list_screen.dart的dispose方法调用Hive.close(),会关闭所有box,再次进入页面时会出现box未打开的错误。

解决方案步骤

1. 统一Box的类型化打开(核心修复)

修改main.dart中的box打开代码,使用类型化方式打开todo_box,确保和后续调用一致:

// 替换原来的 await Hive.openBox('todo_box');
await Hive.openBox<Todo>(HiveBoxes.todo);

这样整个项目中todo_box都会以Box<Todo>类型存在,彻底解决类型冲突。

2. 移除嵌套的MaterialApp

schedule.dart不需要再创建MaterialApp(根MyApp已提供全局配置),直接返回MyHomePage即可:

class schedule extends StatelessWidget {
  const schedule({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MyHomePage(
      title: '스케줄',
    );
  }
}

3. 删除错误的Hive.close()调用

移除list_screen.dart中_MyHomePageState的dispose方法里的Hive.close()——关闭所有box会导致其他页面无法访问数据,应该在整个应用退出时再统一关闭Hive:

@override
void dispose() {
  // 移除 Hive.close();
  super.dispose();
}

4. 验证所有Box调用一致性

确保所有获取todo_box的地方都使用Hive.box<Todo>(HiveBoxes.todo),现有代码中的以下部分已经正确,无需修改:

  • list_screen.dart中的ValueListenableBuilder:valueListenable: Hive.box<Todo>(HiveBoxes.todo).listenable()
  • add_todo_screen.dart中的_onFormSubmit:Box<Todo> contactsBox = Hive.box<Todo>(HiveBoxes.todo);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 18:30:59