我在一个Flutter应用程序中遇到了Hive数据库的几个问题:
-
Hive.initFlutter()
不工作我得到以下错误:
[VERBOSE-2:ui_dart_state.cc(209)] Unhandled Exception: HiveError: You need to initialize Hive or provide a path to store the box.
我试着用appPath调用这个方法,没有,没有区别!如果我使用Hive.init(appPath)
而不是Hive.initFlutter()
,我做没有得到上述异常! 下面是flutter应用程序中的代码:Init
是一个具有许多静态方法来初始化应用程序的类。它在启动屏幕小部件的FutureBuilder
中被调用。首先调用setupLocalHiveDatabase()
方法来初始化Hive并打开所有的box。
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// init Hive and open all boxes
await Init.setupLocalHiveDatabase();
runApp(MyApp());
}
static setupLocalHiveDatabase() async {
print('Setting up hive ...');
var appDocDir = await getApplicationDocumentsDirectory();
print('The application directory is: ${appDocDir.path}');
_setupHive(appDocDir.path);
print('Open all boxes ...');
await Hive.openBox<CreditCard>(HiveBoxes.creditCard,
compactionStrategy: (entries, deletedEntries) => deletedEntries > 10);
await Hive.openBox<ConfigItem>(HiveBoxes.appConfig,
compactionStrategy: (entries, deletedEntries) => deletedEntries > 10);
await Hive.openBox<SupplierOverview>(HiveBoxes.supplier,
compactionStrategy: (entries, deletedEntries) => deletedEntries > 20);
await Hive.openBox<SubscriptionOverview>(HiveBoxes.subscription,
compactionStrategy: (entries, deletedEntries) => deletedEntries > 20);
await Hive.openBox<BscUserProfile>(HiveBoxes.bscUserProfile,
compactionStrategy: (entries, deletedEntries) => deletedEntries > 10);
await Hive.openBox<SyncJob>(HiveBoxes.syncJob,
compactionStrategy: (entries, deletedEntries) => deletedEntries > 10);
await Hive.openBox<SyncProtocol>(HiveBoxes.syncProtocol,
compactionStrategy: (entries, deletedEntries) => deletedEntries > 20);
await Hive.openBox<ClientDevice>(HiveBoxes.clientDevice,
compactionStrategy: (entries, deletedEntries) => deletedEntries > 2);
await Hive.openBox<ClientError>(HiveBoxes.clientError,
compactionStrategy: (entries, deletedEntries) => deletedEntries > 10);
print('done.');
}
static void _setupHive(String path) async {
// We initialize Hive and we give it the current path
print('Initializing Hive databases ...');
//Hive.init(path);
await Hive.initFlutter(path);
print('Registering Hive Adapters...');
Hive.registerAdapter(ConfigItemAdapter()); // ID 1
Hive.registerAdapter(CreditCardAdapter()); // ID 2
Hive.registerAdapter(SubscriptionOverviewAdapter()); // ID 3
Hive.registerAdapter(SupplierOverviewAdapter()); // ID 4
Hive.registerAdapter(ClientErrorAdapter()); // ID 5
Hive.registerAdapter(BscUserProfileAdapter()); //ID 6
Hive.registerAdapter(SyncJobAdapter()); //ID 7
Hive.registerAdapter(PersonAdapter()); // ID 8
Hive.registerAdapter(ContactDataAdapter()); // ID 9
Hive.registerAdapter(SyncProtocolAdapter()); // ID 10
Hive.registerAdapter(ClientDeviceAdapter()); // ID 11
// Enum Types
Hive.registerAdapter(SyncStatesAdapter()); // ID 101
Hive.registerAdapter(SyncDirectionsAdapter()); // ID 102
Hive.registerAdapter(ContractDataObjectTypesAdapter()); // ID 103
Hive.registerAdapter(OperationResultsAdapter()); // ID 104
Hive.registerAdapter(PlatformTypesAdapter()); // ID 106
print('Done with Hive setup.');
}
- 数据未正确保存
我有一个奇怪的情况,数据为空在应用程序重新启动后(热重新加载或完全重新启动)。下面是保存对象后的输出
flutter: UserData: BscUserProfile(0031cd3c-5851-403c-9c11-7ea190db5abf, Debug Test User, debug@test.com, , , [])
如果我做一个热加载数据看起来如下:
flutter: UserData: BscUserProfile(, , , , , [])
对象在数据库中,但为空.
这是省道代码(它是在Init
类如上)
static _setupUser(String userEmail) async {
var userBox = Hive.box<BscUserProfile>(HiveBoxes.bscUserProfile);
//await userBox.deleteAll(userBox.keys);
if (userBox.isEmpty) {
// create a fake user for testing
var user = BscUserProfile(
bscUserEmail: userEmail,
bscUserDisplayName: 'Debug Test User',
bscUserId: Uuid().v4().toString(),
);
await userBox.put(user.bscUserId, user);
GetIt.instance.registerSingleton(user);
for (var user in userBox.values) {
print('UserData: ${user.toString()}');
}
return;
}
// dump database
for (var user in userBox.values) {
print('UserData: ${user.toString()}');
}
var user = userBox.values.firstWhereOrNull((user) => user.bscUserEmail == userEmail);
if (user != null) {
GetIt.instance.registerSingleton(user);
return;
}
}
如果我将第二行取消注释为,则删除框中的所有对象都正确跳转到(userBox.isEmpty)
中,然后显示正确的数据。重新加载后,数据库不为空但是显示空对象!
3。更新不工作第三个问题也是在Init
课上。当应用程序启动时,我持久化了一些特定于设备的数据。更新后,更新的没有反映在应用程序重新启动后的数据库中。下面是一些print语句的输出:
flutter: ClientDevice(e5634285-7e46-4eed-8d89-1a9b4cbfb94d, 93C259F6-EBE2-4079-9B99-E542B714B230, iPhone 11 Pro, iPhone, PlatformTypes.iOS, ios, 11.6, 16, en, gala.local, false, 172.16.63.186)
flutter: Device has changed!
flutter: Current device: ClientDevice(e5634285-7e46-4eed-8d89-1a9b4cbfb94d, 93C259F6-EBE2-4079-9B99-E542B714B230, iPhone 11 Pro, iPhone, PlatformTypes.iOS, iOS, 15.0, 16, en, gala.local, false, 172.16.63.186)
flutter: Persisted device: ClientDevice(e5634285-7e46-4eed-8d89-1a9b4cbfb94d, 93C259F6-EBE2-4079-9B99-E542B714B230, iPhone 11 Pro, iPhone, PlatformTypes.iOS, ios, 11.6, 16, en, gala.local, false, 172.16.63.186)
这里版本11.6重新启动后显示,然后更新为15.0但似乎没有坚持下去。
我不知道我在这里做错了什么,或者在初始化期间改变数据是否有问题,或者是否有Future / async
问题。这很奇怪。如果有人能看出哪里出了问题,我将不胜感激。(我使用AndroidStudio和最新版本的Dart和Flutter)
在main中调用
/// main
void main() async {
/// db init
await Hive.initFlutter();
....
}
我认为你可以使用你的调用结构,但你需要initHive.initFlutter()
没有路径