实际上,我也遇到了这个错误。然而,之前的解决方案都没有帮助到我。我花了几个小时最终明白了,我是在 Web 上下文中进行本地导入操作。
步骤 1:我的 pubsec 中适用于 Web 和 Android 的依赖项
moor: ^4.6.0+1
moor_flutter: ^4.0.0
ffi: ^1.1.2
sqlite3_flutter_libs:
步骤2:根据平台注入我的数据库对象。
service_locator.dart是我在项目中用来注入所有依赖项(数据库、Rest Api客户端等)的文件;你自己可能有另一个名称。
这是我的service_locator.dart的内容:
export 'unsupported.dart'
if (dart.library.ffi) 'service_locator_native.dart'
if (dart.library.html) 'service_locator_web.dart';
正如您所看到的,如果平台是Android,则会导入本地代码;否则,如果是Web,则会导入Web库。
这是service_locator_web.dart的示例:
import 'dart:async';
import 'package:get_it/get_it.dart';
import 'package:my_app/src/dao/chat_channel_dao.dart';
import 'package:drift/web.dart';
final GetIt serviceLocator = GetIt.instance;
initLocator() {
...
...
serviceLocator.registerLazySingleton<ChatContactDao>(() => ChatChannelDao(WebDatabase('db_chat_channels')));
...
}
T get<T extends Object>() {
return serviceLocator.get<T>();
}
registerLazySingleton<T extends Object>(T Function() function){
serviceLocator.registerLazySingleton<T>(function);
}
FutureOr unregister<T extends Object>({
Object? instance,
String? instanceName,
FutureOr Function(T)? disposingFunction,
}){
return serviceLocator.unregister<T>();
}
这是 service_locator_native.dart 的示例:
import 'dart:async';
import 'package:get_it/get_it.dart';
import 'package:my_app/src/dao/chat_channel_dao.dart';
import 'package:drift/native.dart';
final GetIt serviceLocator = GetIt.instance;
initLocator() {
...
...
serviceLocator.registerLazySingleton<ChatContactDao>(
() => ChatChannelDao(makeLazyDb('db_chat_channels.sqlite')));
...
}
T get<T extends Object>() {
return serviceLocator.get<T>();
}
registerLazySingleton<T extends Object>(T Function() function){
serviceLocator.registerLazySingleton<T>(function);
}
LazyDatabase makeLazyDb(String dbName){
final db = LazyDatabase(() async {
final dbFolder = await getApplicationDocumentsDirectory();
final file = File(p.join(dbFolder.path, dbName));
return NativeDatabase(file);
});
return db;
}
对于不支持的平台,这是 unsupported.dart 的代码:
import 'dart:async';
T get<T extends Object>() => throw UnimplementedError();
initLocator() => throw UnimplementedError();
registerLazySingleton<T extends Object>(T Function() function)=> throw UnimplementedError();
FutureOr unregister<T extends Object>() => throw UnimplementedError();
步骤三:调用我的数据库类
import 'package:my_app/src/service/service_locator.dart' as serviceLocator;
class my_sample_ui{
my_sample_method(EntityChatChannel myEntity) async{
var ticketDao = serviceLocator.get<TicketDao>();
await chatChannelDao?.createNew(myEntity);
}
}
结论:
这只是一个设计模式,可以根据您的代码结构进行调整。在此示例中,我使用GetIt来实现类之间的依赖注入。Flutter是一个出色的多平台框架,但我们需要编写多平台代码以确保它在所有环境中都能正常工作。
sqlite3
,但它在 Web 上不受支持 - https://pub.dev/packages/sqlite3 - Tirth Patelsqlite3
的包/插件? - Tirth Patel