HiveError:框“用户”已经打开,类型为Box <User>

时间:2020-08-30 18:28:44

标签: flutter dart hive

我尝试在Hive内使用Mobx,在检查Hive中的用户数据后,我切换到了其他屏幕,例如HomeViewIntro

main.dart

Future<void> main() async {
  ...

  final appDocumentDirectory = await path_provider.getApplicationDocumentsDirectory();
  Hive.init(appDocumentDirectory.path);
  Hive.registerAdapter(UserAdapter());

  _setUpLogging();

  runApp(MultiProvider(providers: providers, child: StartupApplication()));
}

StartupApplication类:我不使用Hive

class StartupApplication extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final isPlatformDark = WidgetsBinding.instance.window.platformBrightness == Brightness.dark;
    final initTheme = isPlatformDark ? nebrassLightTheme : nebrassLightTheme;
    return ThemeProvider(
      initTheme: initTheme,
      duration: const Duration(milliseconds: 400),
      child: Builder(builder: (context) {
        return MaterialApp(
          title: 'TEST',
          theme: ThemeProvider.of(context),
          home: const OverlaySupport(child: OKToast(
           child: MyHomePage() //--> checking user data widget
          )),
          onGenerateRoute: Routes.sailor.generator(),
          navigatorKey: Routes.sailor.navigatorKey,
        );
      }),
    );
  }
}

User类的Hive中检查MyHomePage

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return FutureBuilder<Box<User>>(
            future: Hive.openBox('user'),
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.done) {
                final Box<User> userBox = snapshot.data;
    
                if (userBox.values.isNotEmpty && userBox.get(0).active == 1) {
                  return HomeView();
                } else {
                  return Intro();
                }
              } else {
                return Container();
              }
            });
      }
    
      @override
      void dispose() {
        Hive.close();
        super.dispose();
      }
    }

现在在其他屏幕中,例如我实现了RegisterScreen的{​​{1}}类,并且我想在其中使用MobX框,例如:

user

class Register extends StatefulWidget { @override _RegisterState createState() => _RegisterState(); } class _RegisterState extends State<Register> { TextEditingController _mobileNumber; final GlobalKey<ScaffoldState> _scaffoldState = GlobalKey<ScaffoldState>(); @override void initState() { super.initState(); _mobileNumber = TextEditingController(); } @override Widget build(BuildContext context) { final _registerViewModel = Provider.of<RegisterViewModel>(context, listen: false); return Directionality( textDirection: TextDirection.ltr, child: Scaffold( key: _scaffoldState, ... //_registerViewModel.registerAccount(_mobileNumber.text, '111'); ), ); } void _showSnackBar(String message, BuildContext context) { _scaffoldState.currentState.showSnackBar(SnackBar( content: Directionality( textDirection: TextDirection.rtl, child: Text( '$message', style: AppTheme.of(context).caption().copyWith(color: Colors.white), )))); } } 实现:

MobX

2 个答案:

答案 0 :(得分:0)

  1. 您可以在应用程序的user方法中打开main框:
Future<void> main() async {
  ...

  final appDocumentDirectory = await path_provider.getApplicationDocumentsDirectory();
  Hive.init(appDocumentDirectory.path);
  Hive.registerAdapter(UserAdapter());
  // open the user box
  await Hive.openBox('user');

  _setUpLogging();

  runApp(MultiProvider(providers: providers, child: StartupApplication()));
}
  1. 访问以前打开的框,如下所示:
class MyHomePage extends StatefulWidget {
  const MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  // user box
  Box userBox;

  @override
  void initState() {
    super.initState();
    // get the previously opened user box
    userBox = Hive.box('user');
  }

  @override
  Widget build(BuildContext context) {
    // check for your conditions 
    return (userBox.values.isNotEmpty && userBox.get(0).active == 1)
        ? HomeView()
        : Intro();
  }
}

答案 1 :(得分:0)

我第一次尝试了 Hive 并观察了这一点。

如果你像这样打开盒子:

await Hive.openBox("MyModelBox");

如果你不这样做,它会抛出异常:

BoxBase<E> _getBoxInternal<E>(String name, [bool? lazy]) {
    var lowerCaseName = name.toLowerCase();
    var box = _boxes[lowerCaseName];
    if (box != null) {
      if ((lazy == null || box.lazy == lazy) && box.valueType == E) {
        return box as BoxBase<E>;
      } else {
        var typeName = box is LazyBox
            ? 'LazyBox<${box.valueType}>'
            : 'Box<${box.valueType}>';
        throw HiveError('The box "$lowerCaseName" is already open '
            'and of type $typeName.');
      }
    } else {
      throw HiveError('Box not found. Did you forget to call Hive.openBox()?');
    }
  }

box.valueType 将是 dynamicE 将是您的类模型类型 MyModel。因此它们不会相等。

但是如果您传递特定类型的模型

await Hive.openBox<MyModel>("MyModelBox");

错误消失。