嘗試在 Flutter 中訪問 Hive 數據庫時,“聯繫人”框已打開且類型為 Box<Contact> (The box "contacts" is already open and of type Box<Contact> when trying to access Hive database in flutter)


問題描述

嘗試在 Flutter 中訪問 Hive 數據庫時,“聯繫人”框已打開且類型為 Box (The box "contacts" is already open and of type Box when trying to access Hive database in flutter)

我在main中初始化box數據庫如下

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

然後我使用FutureBuilder插件在material app中打開box如下:

  FutureBuilder(
      future: Hive.openBox<Contact>('contacts'),
      builder: (context, snapshot) {
        if(snapshot.connectionState == ConnectionState.done){
          if(snapshot.hasError){
            return Text(snapshot.error.toString() );
          }
          return ContactPage();
        } else {
          return Scaffold();
        }
      }
    ),

在ContactPage()裡面

我創建了這個:‑

  ValueListenableBuilder(
                valueListenable: Hive.box<Contact>('contacts').listenable(),
                builder: (context,Box<Contact> box,_){
                  if(box.values.isEmpty){
                    return Text('data is empty');
                  } else {
                    return ListView.builder(
                      itemCount: box.values.length,
                      itemBuilder: (context,index){
                        var contact = box.getAt(index);
                        return ListTile(
                          title: Text(contact.name),
                          subtitle: Text(contact.age.toString()),
                        );
                      },
                    );
                  }
                },
               )

當我運行應用程序時出現以下錯誤

The following HiveError was thrown while handling a gesture:
The box "contacts" is already open and of type Box<Contact>.

當我嘗試使用該框時不打開它,我得到錯誤意味著盒子沒有打開。

我必須使用盒子而不在 ValueListenableBuilder 中打開它嗎?但是我必須在不同的小部件中再次打開同一個框才能在其上添加數據。


參考解法

方法 1:

I'm jumping on this thread because I had a hard time trying to figure out how to deal with the deprecated WatchBoxBuilder while using the resocoder's Hive tutorial, and a google search led me here.

This is what I ended up using:

main.dart:

void main() async {
  if (!kIsWeb) { // <‑‑ I put this here so that I could use Hive in Flutter Web
    final dynamic appDocumentDirectory =
        await path_provider.getApplicationDocumentsDirectory();
    Hive.init(appDocumentDirectory.path as String);
  }
  Hive.registerAdapter(ContactAdapter());

  runApp(child: MyApp());
}

and then ContactPage() (note: it's the same as OP's):

Widget _buildListView() {
  return ValueListenableBuilder(
    valueListenable: Hive.box<Contact>('contacts').listenable(),
    builder: (context, Box<Contact> box, _) {
      if (box.values.isEmpty) {
        return Text('data is empty');
      } else {
        return ListView.builder(
          itemCount: box.values.length,
          itemBuilder: (context, index) {
            var contact = box.getAt(index);
            return ListTile(
              title: Text(contact.name),
              subtitle: Text(contact.age.toString()),
            );
          },
        );
      }
    },
  );
}

方法 2:

Its a simple explanation actually:

1. It only occurs when your box has a generic type like

Hive.openBox<User>('users')

2. So once you call Hive.box('users') without specifying the generic type this error occurs.

THATS EVERYTHING.</p>

SOLUTION Hive.box<User>('users') at each call :)

方法 3:

It is probably because you are trying to open the box inside FutureBuilder. If somehow it tries to rebuild itself, it will try to open the box which is already opened. Can you try to open the box after you register the adapter like:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final appDocumentDirectory = await path_provider.getApplicationDocumentsDirectory();
  Hive.init(appDocumentDirectory.path);
  Hive.registerAdapter(ContactAdapter());
  await Hive.openBox<Contact>('contacts');
  runApp(MyApp());
}

And instead of FutureBuilder just return ContactPage

方法 4:

In main.dart file :

future: Hive.openBox('contacts'),
      builder: (BuildContext context, AsyncSnapshot snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          if (snapshot.hasError) {
            return Text(snapshot.error.toString());
          } else {
            return ContactPage();
          }
        } else {
          return Center(
            child: CircularProgressIndicator(),
          );
        }
      },

In ContactPage:

return WatchBoxBuilder(
box: Hive.box('contacts'),
builder: (context, contactBox) {
  return ListView.builder(
    itemCount: contactBox.length,
    itemBuilder: (context, index) {
      final contact = contactBox.getAt(index) as Contact;
      return ListTile(
        title: Text(contact.name),
        subtitle: Text(contact.number),
        trailing: Row(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            IconButton(
              icon: Icon(Icons.refresh),
              onPressed: () {
                contactBox.putAt(
                  index,
                  Contact('${contact.name}*', contact.number),
                );
              },
            ),
            IconButton(
              icon: Icon(Icons.delete),
              onPressed: () {
                contactBox.deleteAt(index);
              },
            ),
          ],
        ),
      );
    },
  );
},

);

It's OK to open the box in future call..

(by aboodrakWilliam TerrillRay ZionSelim KundakçıoğluMhamza007)

參考文件

  1. The box "contacts" is already open and of type Box when trying to access Hive database in flutter (CC BY‑SA 2.5/3.0/4.0)

#flutter-hive #Database #Flutter






相關問題

如何從 Flutter Hive 中檢索 HiveList (How to retrieve HiveList from Flutter Hive)

嘗試在 Flutter 中訪問 Hive 數據庫時,“聯繫人”框已打開且類型為 Box<Contact> (The box "contacts" is already open and of type Box<Contact> when trying to access Hive database in flutter)

更新 Hive 框中最喜歡的字段的布爾值 (Updating Boolean value in Hive box for favorite field)

用 Mockito Flutter 模擬 Hive (Mocking Hive with Mockito Flutter)

Flutter 中 Hive 框中的記錄過濾和排序 (Filter and sort records from Hive box in Flutter)

在 Flutter 中驗證 Hive secureBox 的加密 (Verifying encryption of Hive securedBox in Flutter)

提供者:在構建期間調用的 setState() 或 markNeedsBuild() (Provider: setState() or markNeedsBuild() called during build)

如何設置 StateNotifierProvider 的狀態 (How to set state of StateNotifierProvider)

如何使用 HIVE、Flutter 為兩個不同的 Modal 類註冊兩個適配器? (How to register two Adapters for two different Modal classes with HIVE , Flutter?)

錯誤:Flutter Hive 中的“類型‘UnspecifiedInvalidResult’不是類型轉換中‘LibraryElementResult’類型的子類型” (Error: "type 'UnspecifiedInvalidResult' is not a subtype of type 'LibraryElementResult' in type cast" in Flutter Hive)

Flutter 將 Hive 數據庫與 Riverpod 集成 (Flutter integrating Hive database with Riverpod)

在蜂巢顫動中保存對象列表 (Save list of object in hive flutter)







留言討論