dart 重新启动应用程序后保存自定义对象,自定义对象列表消失

ctrmrzij  于 2023-04-09  发布在  其他
关注(0)|答案(2)|浏览(223)

我有一个Flutter应用程序,它从网站检索JSON文档,然后使用Hive保存它。我有一个LocalDatabase类,它扩展了HiveObject,包含几个对象和自定义对象列表。
下面是LocalDatabase类的代码:

part 'hive_storage.g.dart';

@HiveType(typeId: 0)
class LocalDatabase extends HiveObject {
  @HiveField(0)
  DateTime? lastUpdate;
  
  List<Schulaufgaben>? examDates;
  
  List<AllgemeineTermine>? appointments;
  
  Schulinformationen? schoolInformation;
}

Schulaufgaben和AllgemeineTermine类是自定义对象,它们有自己的fromJson()和toJson()方法用于序列化和反序列化。LocalDatabase类也有使用Hive的代码生成(hive_generator)生成的相应Hive适配器。
我可以在应用运行时使用Hive保存和检索数据。但是,重新启动应用后,LocalDatabase对象中除lastUpdate外的所有对象和自定义对象列表均为null。
我已经在main函数中正确初始化了Hive,如下所示:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Hive.initFlutter();
  Hive.registerAdapter(LocalDatabaseAdapter());
  await Hive.openBox<LocalDatabase>('localDatabase');
  runApp(const MyApp());
}

下面是我从网站检索数据后如何将LocalDatabase对象保存到Hive:

final localDatabase = Boxes.getSavedDatabase();

final databaseObject = LocalDatabase()
  ..lastUpdate = DateTime.now()
  ..examDates = await _db.getExamDates()
  ..appointments = await _db.getAppointments();

localDatabase.add(databaseObject);

我不知道为什么自定义对象和自定义对象的列表在重新启动应用程序后没有在Hive中持久化。
我还检查了自定义对象和自定义对象列表是否使用Hive.registerAdapter()在Hive中正确注册。
我在Stack Overflow上提到过类似的问题(链接:Flutter Hive save custom object with list of custom objects gone after restarting app),但那里提供的解决方案对我不起作用。我也尝试过使用hive_flutter包来实现Flutter特定的实现,但问题仍然存在。

oxcyiej7

oxcyiej71#

看起来问题在于如何从Hive中检索LocalDatabase对象。当您调用localDatabase.add(databaseObject)时,实际上每次重新启动应用程序时都会向Hive框添加新的LocalDatabase对象,而不是更新现有对象。
要正确地从Hive检索LocalDatabase对象,您应该调用localDatabase.getAt(0)而不是Boxes.getSavedDatabase()getAt()方法检索框中指定索引处的对象,因此调用getAt(0)将为您提供框中的第一个(在本例中,也是唯一的)LocalDatabase对象。

final localDatabaseBox = await Hive.openBox<LocalDatabase>('localDatabase');
final databaseObject = LocalDatabase()
  ..lastUpdate = DateTime.now()
  ..examDates = await _db.getExamDates()
  ..appointments = await _db.getAppointments();

localDatabaseBox.putAt(0, databaseObject);

下面是如何从Hive中检索LocalDatabase对象:

final localDatabaseBox = await Hive.openBox<LocalDatabase>('localDatabase');
final localDatabase = localDatabaseBox.getAt(0);

因此,本质上,通过使用putAt()而不是add(),您正在更新框中现有的LocalDatabase对象,而不是每次都添加一个新对象。

k5ifujac

k5ifujac2#

您应该将所有字段标记为HiveField(本地保存所需的字段),即使它们是自定义对象和扩展配置单元类。

@HiveType(typeId: 0)
class LocalDatabase extends HiveObject {
  @HiveField(0)
  DateTime? lastUpdate;
  @HiveField(1)
  List<Schulaufgaben>? examDates;
  @HiveField(2)
  List<AllgemeineTermine>? appointments;
  
  Schulinformationen? schoolInformation;
}

相关问题