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

Flutter+Hive在FutureBuilder中判断Box值提示未打开Box如何解决

问题根因

  1. 你在build方法的起始位置就执行了final user = Hive.box('user'),这时候FutureBuilder的Hive.openBox('user')异步操作还未完成,box还没有被初始化,所以直接调用Hive.box()就会抛出找不到box的错误。
  2. 异步操作完成后你又重复调用了一次Hive.openBox('user'),属于多余操作,FutureBuilder的future参数已经帮你完成了打开box的操作。
  3. 另外你的MyApp类的createState返回类型写错了,你定义的State是_PocketPolarixState,但是StatefulWidget是MyApp,这里会有类型错误。

修正后的完整代码

import 'package:flutter/material.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:path_provider/path_provider.dart' as path_provider;
import 'package:myapp/model/user_model.dart';
import 'package:myapp/views/login_view.dart';
import 'package:myapp/views/project_view.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final appDocsDir = await path_provider.getApplicationDocumentsDirectory();
  Hive.init(appDocsDir.path);
  Hive.registerAdapter(UserModelAdapter());
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  // 修正返回的State类型
  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Startup Name Generator',
      theme: ThemeData(
        appBarTheme: const AppBarTheme(
          backgroundColor: Color(0xFF2036B8),
          foregroundColor: Colors.white,
        ),
      ),
      home: FutureBuilder(
        future: Hive.openBox('user'),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            if (snapshot.hasError) {
              return Scaffold(
                body: Center(child: Text(snapshot.error.toString())),
              );
            } else {
              // 打开完成后再获取box,此时box已经初始化完成
              final userBox = Hive.box('user');
              if (userBox.get('token') != null) {
                return const ProjectView();
              } else {
                return const LoginView();
              }
            }
          } else {
            // 加载过程中显示加载指示器,避免空白页
            return const Scaffold(
              body: Center(child: CircularProgressIndicator()),
            );
          }
        },
      ),
    );
  }

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

额外优化建议

你也可以直接在main方法里提前打开user box,就不用在页面里加FutureBuilder了,逻辑更简洁:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final appDocsDir = await path_provider.getApplicationDocumentsDirectory();
  Hive.init(appDocsDir.path);
  Hive.registerAdapter(UserModelAdapter());
  // 提前打开box
  await Hive.openBox('user');
  runApp(const MyApp());
}

之后在MyApp的build方法里就可以直接判断token,不需要FutureBuilder包裹。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 14:36:07