【问题标题】:Reading Hivebox value is returning List<dynamic> instead of saved List<Object>读取 Hivebox 值返回 List<dynamic> 而不是保存的 List<Object>
【发布时间】:2025-11-30 05:40:01
【问题描述】:

我将列表保存到 Hive Box 中的索引。

class Person { 
 String name;
 Person(this.name);
}

List<Person> friends = [];
friends.add(Person('Jerry'));

var accountBox = Hive.openBox('account');
accountBox.put('friends',friends);

//Testing as soon as saved to make sure it's storing correctly.
List<Person> friends = accountBox.get('friends');
assert(friends.length == 1);

所以这一切都按预期工作。 由于某种疯狂的原因,当我热启动应用程序并尝试从 Hive 获取朋友列表时,它不再返回 List&lt;Person&gt;。它返回一个List&lt;dynamic&gt;

var accountBox = Hive.openBox('account');
List<Person> friends = accountBox.get('friends');

///ERROR
E/flutter (31497): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled
Exception: type 'List<dynamic>' is not a subtype of type 'List<Person>'
E/flutter (31497): <asynchronous suspension>
etc...

这可能是什么原因造成的?这太不寻常了。

【问题讨论】:

    标签: flutter dart flutter-hive


    【解决方案1】:

    Hive 主要是一个带有文件缓存的内存数据库。当应用程序运行时,它可能会将您放入其中的对象按原样存储在内存中,但将对象作为序列化二进制数据存储在缓存文件中。这意味着只要应用程序处于打开状态,您就会得到您的Person 列表,但它不知道如何从缓存文件中获取该数据。结果是 Hive 尽最大努力反序列化数据并将其作为 dynamic 返回给您,但没有更多信息,它已经尽了最大努力。

    如果您想在应用关闭后保持数据完整,您需要告诉 Hive 如何(反)序列化您的类型。为此,请使用 Hive 注释适当地标记您的类。

    @HiveType(typeId: 0)
    class Person extends HiveObject { 
      @HiveField(0)
      String name;
    
      Person(this.name);
    }
    

    【讨论】:

      【解决方案2】:

      有一种简单的方法可以转换回您的信息。

      List<T> myList = box.get('key', defaultValue: <T>[]).cast<T>();
      

      正如您在此示例中看到的那样,当您获取数据时,您只需要告诉类型即可正确分配数据。

      【讨论】:

        【解决方案3】:

        这解决了我的问题

        var fooBox = await Hive.openBox<List>("Foo");
        
        var foosList = fooBox.get("foos", defaultValue: []).cast<Foo>();
        print(foosList);
        

        这个解决方案来自github issue

        【讨论】: