Flutter异步编程isolate

在Android等移动端的开发中,涉及的所有网络操作都不能运行在主线程中。Flutter的网络操作都是通过异步Future进行修饰的,而调用者不需要等待动作返回,也不会造成页面的卡顿。但是,这些异步操作本质上还是Dart语言的并发方案。在Flutter中异步编程与Java不一样,Flutter是单线程运行,也就是说没有多线程的概念,但是Flutter有一个新的概念—隔离,用于实现异步的操作。

隔离是什么?

Flutter的Dart代码是运行在隔离上的,对应的UI主线程在Flutter中称为主隔离(main isolate),我们可以创建一些子隔离用于运行耗时的网络操作,而这些隔离是通过Flutter引擎层的一个线程来控制实现的,而实现隔离的线程又是由Flutter创建和管理的。

隔离的使用

隔离之间的内存是独立的,它们之间进行通信就需要用到Port,一个隔离可以有多个Port,但是Port只有两个类型:ReceivePort和SendPort。其中,ReceivePort是一个接收消息的事件流,SendPort则允许发送消息给ReceivePort。SendPort可以由ReceivePort生成,它将所有的消息发送给对应的ReceivePort。

 _main() async {
    
    
    final receivePort = ReceivePort();
    //创建隔离
    await Isolate.spawn(_isolate2, receivePort.sendPort);
    //发送消息
    var sendPort = await receivePort.first;
    var message = await sendMessage(sendPort, "哈喽");
    print('Main_Isolate:$message');
  }

  void _isolate2(SendPort message) async {
    
    
    //创建一个ReceivePort
    var port = ReceivePort();
    //把它发送给主隔离
    message.send(port.sendPort);
    port.listen((message) {
    
    
      SendPort send = message[0] as SendPort;
      String str = message[1] as String;
      print('Isolate2:$str');
      send.send("message");
      port.close();
    });
  }

  Future sendMessage(sendPort, String message) async {
    
    
    ReceivePort receivePort = ReceivePort();
    sendPort.send([receivePort.sendPort, message]);
    return receivePort.first;
  }

在一个隔离中创建另一个隔离被称为spawning。除了spawn()方法生成隔离外,还可以用spawnUri()方法,它是基于给定库的URI来生成一个隔离。

隔离的简单使用

上面隔离的使用比较复杂,对于一些只有一次返回的异步请求,使用上面的方式显然不那么划算了。这时候可以使用Flutter提供的compute()函数,它只有两个参数,第一个参数是需要执行耗时任务的名称,第二个参数是前面方法需要传递的参数。此外,compute()函数中运行的方法必须是顶级方法或者是static方法,并且compute()函数只能传递一个参数,返回值也只有一个。

  Future<bool> isPrime(int value) {
    
    
    return compute(_calculate, value);
  }

  bool _calculate(int value) {
    
    
    if (value == 1) {
    
    
      return false;
    }
    for (int i = 2; i < value; ++i) {
    
    
      if (value % i == 0) {
    
    
        return false;
      }
    }
    return true;
  }

总结

对于一些需要多次返回的场景,比如我们socket长链接与后台通信,这时候如果使用compute函数就不能满足需求了,所以对于这类场景只能使用isolate来实现。

猜你喜欢

转载自blog.csdn.net/Memory_of_the_wind/article/details/130941094