读取 Hivebox 值返回 List<dynamic> 而不是保存的 List<Object>

Reading Hivebox value is returning List<dynamic> instead of saved List<Object>

我将列表保存到 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 获取好友列表时,它不再是 returns 和 List<Person>。它returns一个List<dynamic>

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...

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

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

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

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

  Person(this.name);
}

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

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

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

这解决了我的问题

var fooBox = await Hive.openBox<List>("Foo");

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

此解决方案来自 github issue