Flutter Dart-在隔离中调用sqflite函数会导致错误

时间:2019-06-29 15:29:40

标签: flutter dart-isolates

我有一个有效的sqflite数据库,单元测试有效。我想在onTap方法中调用sqflite方法。我了解我无法在主UI线程中执行sqflite函数(Flutter在运行时告诉我)。因此,我创建了一个隔离来调用sqflite函数,该函数给出了另一个错误。如果不调用sqflite函数,则隔离有效;如果仅返回布尔值,则隔离有效。这是代码和异常-谢谢您的建议:


用户界面中的代码段

    Widget loginButton(BuildContext context) {
    return Expanded(
      child: Padding(
        padding: const EdgeInsets.only(left: 20.0, right: 5.0, top: 20.0, bottom: 0.0),
        child: GestureDetector(
          onTap: () {
            if (emailController.text.length > 1 && passwordController.text.length > 7) {
              /// Find user. Then...
              doCheckIfFoundUser(emailController.text.trim(), passwordController.text);
            } else {
              printUserNotFound();
            }

          },
        child: buttonContainer(Colors.indigo, "Login", 20.0),
        ),
      ),
    );

从用户界面调用的方法

doCheckIfFoundUser(String email, String password) async {
    var result;
    List<String> emailPasswordList = new List();
    emailPasswordList.add(email);
    emailPasswordList.add(password);
    var receivePort = new ReceivePort();
    Isolate.spawn(callbackFunction, receivePort.sendPort);
    SendPort sendPort = await receivePort.first;
    var ans = await sendReceive(sendPort, emailPasswordList);
    setState(() {
      result = ans;
      print("The value is $result - please do your thing");
    });
}

隔离回调

static void callbackFunction(SendPort callerSendPort) async {

    ReceivePort newIsolateReceivePort = ReceivePort();


    callerSendPort.send(newIsolateReceivePort.sendPort);
    var msg = await newIsolateReceivePort.first;
    List<String> emailPasswordList = msg[0];

    print("email: ${emailPasswordList[0]}, password: ${emailPasswordList[1]}");

    bool foundUser = await searchForUser(emailPasswordList[0], emailPasswordList[1]);
    SendPort replyPort = msg[1];
    replyPort.send(foundUser);
}
Future sendReceive(SendPort send, message) {
  ReceivePort receivePort = ReceivePort();
  send.send([message, receivePort.sendPort]);
  return receivePort.first;}

  

I / flutter(2073):电子邮件:电子邮件,密码:Passw0rd

     

E / flutter(2073):[错误:flutter / runtime / dart_isolate.cc(805)]未处理的异常:

     

E / flutter(2073):错误:找不到本机函数'Window_sendPlatformMessage'(4个参数)

     

E / flutter(2073):#0 Window.sendPlatformMessage(dart:ui / window.dart:1089:9)

     

E / flutter(2073):#1 _DefaultBinaryMessenger._sendPlatformMessage(package:flutter / src / services / binary_messenger.dart:85:15)

     

E / flutter(2073):#2 _DefaultBinaryMessenger.send(package:flutter / src / services / binary_messenger.dart:129:12)

     

E / flutter(2073):#3 MethodChannel.invokeMethod(package:flutter / src / services / platform_channel.dart:309:51)

     

E / flutter(2073):

     

E / flutter(2073):#4 invokeMethod(package:sqflite / src / sqflite_impl.dart:18:34)

     

E / flutter(2073):

     

E / flutter(2073):#5 SqfliteDatabaseFactoryImpl.invokeMethod(包:sqflite / src / factory_impl.dart:33:7)

     

E / flutter(2073):#6 _SqfliteDatabaseFactoryImpl&Object&SqfliteDatabaseFactoryMixin.safeInvokeMethod。 (package:sqflite / src / factory_mixin.dart:22:35)

     

E / flutter(2073):#7 wrapDatabaseException(package:sqflite / src / exception_impl.dart:7:34)   E / flutter(2073):。

     

E / flutter(2073):#8 SqfliteDatabaseFactoryImpl.wrapDatabaseException(package:sqflite / src / factory_impl.dart:29:7)。

     

E / flutter(2073):#9 _SqfliteDatabaseFactoryImpl&Object&SqfliteDatabaseFactoryMixin.safeInvokeMethod(包:sqflite / src / factory_mixin.dart:22:7)。   E / flutter(2073):#10 _SqfliteDatabaseFactoryImpl&Object&SqfliteDatabaseFactoryMixin.getDatabasesPath(package:sqflite / src / factory_mixin.dart:136:17)。   E /颤振(2073):   E / flutter(2073):#11 getDatabasesPath。 (包裹:sqflite / sqflite.dart:166:54)   E / flutter(2073):#12 UsersSqflite.init(package:himrepo / controller / users_database.dart:20:47)。   E / flutter(2073):。   E / flutter(2073):#13 _LoginPageState.searchForUser。 (包装:himrepo / ui / login.dart:268:24)。   E / flutter(2073):。   E / flutter(2073):#14 _LoginPageState.callbackFunction(package:himrepo / ui / login.dart:166:28)。   E / flutter(2073):。   E / flutter(2073):#15 _startIsolate ..(dart:isolate-patch / isolate_patch.dart:304:17)。   E / Flutter(2073):#16 _RawReceivePortImpl._handleMessage(dart:isolate-patch / isolate_patch.dart:172:12)。

直接执行Sqflite方法会给出

E/AndroidRuntime( 6628): FATAL EXCEPTION: Sqflite
E/AndroidRuntime( 6628): java.lang.RuntimeException: Methods marked with @UiThread must be executed on the main thread. Current thread: Sqflite
E/AndroidRuntime( 6628):    at io.flutter.embedding.engine.FlutterJNI.ensureRunningOnMainThread(FlutterJNI.java:794)
E/AndroidRuntime( 6628):    at io.flutter.embedding.engine.FlutterJNI.invokePlatformMessageResponseCallback(FlutterJNI.java:727)
E/AndroidRuntime( 6628):    at io.flutter.embedding.engine.dart.DartMessenger$Reply.reply(DartMessenger.java:140)
E/AndroidRuntime( 6628):    at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler$1.success(MethodChannel.java:225)
E/AndroidRuntime( 6628):    at com.tekartik.sqflite.SqflitePlugin$6.run(SqflitePlugin.java:778)
E/AndroidRuntime( 6628):    at android.os.Handler.handleCallback(Handler.java:873)
E/AndroidRuntime( 6628):    at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime( 6628):    at android.os.Looper.loop(Looper.java:193)
E/AndroidRuntime( 6628):    at android.os.HandlerThread.run(HandlerThread.java:65)


1 个答案:

答案 0 :(得分:0)

感谢@pskink的帮助。隔离有效,但是从Widget onTap事件运行sqflite时出现异常。原来,我包含在pubspec.yaml中的一个插件(json_annotation)在某种程度上导致了该异常:“标有@UiThread的方法必须在主线程上执行。当前线程:Sqflite”。删除该插件后,该应用即可正常工作。