报告前请仔细阅读。
我的 flutter web 项目运行得很好。几个小时后,它开始抱怨 'dart:ffi: 我什至没有导入。我看到了类似的问题,但没有一个是我的情况。我尝试了所有能找到的东西,但没有任何效果。错误如下:
/C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/drift-1.7.1/lib/src/sqlite3/database_tracker.dart:1:8: Error: Not found: 'dart:ffi'
import 'dart:ffi';
^
/C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/sqlite3-1.8.0/lib/src/ffi/api/database.dart:1:8: Error: Not found: 'dart:ffi'
import 'dart:ffi';
^
/C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/sqlite3-1.8.0/lib/src/ffi/api/statement.dart:1:8: Error: Not found: 'dart:ffi'
import 'dart:ffi';
^
/C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/sqlite3-1.8.0/lib/open.dart:5:8: Error: Not found: 'dart:ffi'
import 'dart:ffi';
^
...
Failed to compile application.
Exited (sigterm)
我无法包含整个调试控制台的输出,但这些是顶行和底行。 请帮忙,谢谢。
就我而言,
import 'dart:ffi'
可能是由我的 IDE 自动添加到我的项目中的。我只是用 IDE 的搜索功能进行搜索,然后删除了导入。
确实,我也遇到了这个错误。但是,以前的解决方案都没有帮助我。我花了几个小时,终于明白我是在网络环境中进行本地导入。 我制作的应用程序可以在 Android 和 Web 上编译。我是怎么做到的?
第 1 步:我的 pubsec 中对 Web 和 Android 的依赖
#SQLITE with moore for all platforms
moor: ^4.6.0+1
moor_flutter: ^4.0.0
ffi: ^1.1.2
# for sqlite on android
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';//database class
import 'package:drift/web.dart';//only for the web
final GetIt serviceLocator = GetIt.instance;
initLocator() {
...
//Environment Settings
...
//DAO Injection
serviceLocator.registerLazySingleton<ChatContactDao>(() => ChatChannelDao(WebDatabase('db_chat_channels')));
...
}
//to fake the interpreter to see service_locator like an getIt Instance
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';//database class
import 'package:drift/native.dart';//only for the native platform
final GetIt serviceLocator = GetIt.instance;
initLocator() {
...
//Environment Settings
...
//DAO Injection
serviceLocator.registerLazySingleton<ChatContactDao>(
() => ChatChannelDao(makeLazyDb('db_chat_channels.sqlite')));//here for native DB
...
}
//to fake the interpreter to see service_locator like an getIt Instance
T get<T extends Object>() {
return serviceLocator.get<T>();
}
registerLazySingleton<T extends Object>(T Function() function){
serviceLocator.registerLazySingleton<T>(function);
}
// to call native Db Builder
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();
第3步:调用我的DB类
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);
}
//implements your own methods
}
结论: 这只是一个可以帮助大家的设计模式,可以根据您的代码结构进行调整。在此示例中,我使用 GetIt 进行类之间的依赖注入。 Flutter是一个出色的多平台框架,但我们需要编写多平台代码以确保它在所有环境下都能工作。
我刚刚遇到此错误,并删除了所有小部件文件中所有未使用的导入,并且错误停止出现。我希望这能解决您的问题。
您可以将鼠标悬停在 上删除 import 'dart:ffi';
/C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/drift-1.7.1/lib/src/sqlite3/database_tracker.dart:1:8: Error: Not found: 'dart:ffi'
然后按 Windows 上的 ctrl 按钮,然后单击鼠标左键,这将带您到错误位置,在顶部您将找到导入“dart:ffi” 删除它或评论它。
在终端上输入 flutter install dart:ffi 如果您收到此错误,我认为这会对您有所帮助
我不知道它是否适用于所有场景,但我也刚刚删除了“dart:ffi”导入并且它起作用了
对于网页版本,您必须使用这样的连接
import 'package:drift/drift.dart';
import 'package:drift/wasm.dart';
import 'package:flutter/foundation.dart';
part 'app_database.g.dart';
@DriftDatabase(tables: [YOUR_TABLE_NAME])
class AppDatabase extends _$AppDatabase {
AppDatabase() : super(_connect());
@override
int get schemaVersion => 1;
}
DatabaseConnection _connect() {
return DatabaseConnection.delayed(Future(() async {
final db = await WasmDatabase.open(
databaseName: 'YOUR_DB_NAME',
sqlite3Uri: Uri.parse('sqlite3.wasm'),
driftWorkerUri: Uri.parse('drift_worker.js'),
);
if (db.missingFeatures.isNotEmpty) {
debugPrint('Using ${db.chosenImplementation} due to unsupported '
'browser features: ${db.missingFeatures}');
}
return db.resolvedExecutor;
}));
}
并将其用于移动版本:
import 'dart:io';
import 'package:drift/native.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p;
import 'package:sqlite3/sqlite3.dart';
import 'package:sqlite3_flutter_libs/sqlite3_flutter_libs.dart';
// ... the TodoItems table definition stays the same
@DriftDatabase(tables: [TodoItems])
class AppDatabase extends _$AppDatabase {
AppDatabase() : super(_openConnection());
@override
int get schemaVersion => 1;
}
LazyDatabase _openConnection() {
// the LazyDatabase util lets us find the right location for the file async.
return LazyDatabase(() async {
// put the database file, called db.sqlite here, into the documents folder
// for your app.
final dbFolder = await getApplicationDocumentsDirectory();
final file = File(p.join(dbFolder.path, 'db.sqlite'));
// Also work around limitations on old Android versions
if (Platform.isAndroid) {
await applyWorkaroundToOpenSqlite3OnOldAndroidVersions();
}
// Make sqlite3 pick a more suitable location for temporary files - the
// one from the system may be inaccessible due to sandboxing.
final cachebase = (await getTemporaryDirectory()).path;
// We can't access /tmp on Android, which sqlite3 would try by default.
// Explicitly tell it about the correct temporary directory.
sqlite3.tempDirectory = cachebase;
return NativeDatabase.createInBackground(file);
});
}
对我来说,我只是找到了 dart:ffi 的导入位置并删除了它,现在我的网络再次正常工作了
我想通了。我刚刚删除了“web_ffi”文件夹,它以某种方式起作用了。