Flutter 异步任务Isolate传递参数问题

场景是需要一个解压缩的操作,因为耗时,所以在子线程(姑且叫子线程)里执行,但是用无论用compute还是isolate都会报这个错
If you're running an application and need to access the binary messenger before runApp() has been called (for example, during plugin initialization), then you need to explicitly call the WidgetsFlutterBinding.ensureInitialized()

flutter ( 6234): ServicesBinding.defaultBinaryMessenger was accessed before the binding 

was initialized. I/flutter ( 6234): If you're running an application and need to access the binary 

messenger before runApp() has been called (for example, during plugin initialization), then 

you need to explicitly call the WidgetsFlutterBinding.ensureInitialized() first. I/flutter ( 6234): If 

you're running a test, you can call the TestWidgetsFlutterBinding.ensureInitialized() as the first 

line in your test's main() method to initialize the binding.

WidgetsFlutterBinding.ensureInitialized() 问题 ,去到main里加上之后,还是不好使,然后去stackflow上找了半天,找到了这个
https://stackoverflow.com/questions/62649795/servicesbinding-defaultbinarymessenger-problem-while-using-flutters-compute-fun

ok基本上是这个问题了,在子线程中也调用了这个类似的方法

  Future getPhoneLocalPathApp() async {
    final directory =await getApplicationDocumentsDirectory();
    return directory.path;
  }

Currently Flutter platform channel has limitation - communications are only supported by the main isolate which created when your application launched.
这句话翻译过来主要意思就是 和原生的通信只支持在main isolate中执行,项目中还有一个获取权限的也是,解决的办法就是把这些和原生通信的方法都提取出来,放在主线程就好了。flutter中的两个线程之间数据不共享,内存隔离,还好理解,但是居然和原生的方法都给隔离了,这就真过分了。
继续搞又遇到一个问题,main isolate和新开的 isolate在通信的时候,总是要等新开isolate耗时任务结束后才能收到main isolate的消息,也就是新开子isolate的消息是先到的,main isolate的消息再过来,耗时任务都完成了,那耗时任务需要的参数怎么传呢?这就有点奇怪了,暂时没搞懂为什么,后续再研究。但是也能解决,那就是先不执行耗时操作,先在两个isolate之间传递一遍消息,保证通信成功后,再进行传递消息值。

main isolate里的方法

  var i = "sss,ddd,bbb"; //需要传递的参数值
  // 创建一个消息接收器
  var receivePort = new ReceivePort();

  //将消息接收器当中的发送器 发给 子 isolate
 Isolate.spawn(entryPoint2, receivePort.sendPort);

  //从消息接收器中读取消息
  receivePort.listen((t) {
    print("接收到其他isolate发过来的消息!$t");
   
    if (t[0]==0) { //接收到了 子isolate 的 发送器
      t[1].send(1);

    } else if(t[0]==1) {//接收到通信连接成功,可以发送参数了
      t[1].send(i); //
    }
  });
  

新开isolate方法

void entryPoint(SendPort sendPort) {
  //print(i);
  var receivePort = new ReceivePort();

  var sendPort2 = receivePort.sendPort;

  sendPort.send([0,sendPort2]);

  receivePort.listen((t){
    print("接收到main isolate发过来的消息 $t");

    if(t==1){
      sendPort.send([1,sendPort2]); //子线程告诉主线程 可以开始给我参数了
    }
    if(t is String){
      //ok 此时可以做耗时操作了
      sleep(Duration(seconds: 4));
      print("我的做耗时操作完了");
    }
  });
  
}

如果大家有其他好方法,欢迎讨论。

你可能感兴趣的:(Flutter 异步任务Isolate传递参数问题)