美文网首页
Flutter怎么处理耗时操作?(异步和线程)

Flutter怎么处理耗时操作?(异步和线程)

作者: shiyueZ | 来源:发表于2021-06-23 10:56 被阅读0次

    Flutter是单线程任务执行模式,默认情况下只会在主线程运行。那么碰到耗时操作如:网络请求、图片加载、数据库操作等,Flutter该如何处理呢?

    Dart提供了两个关键词来实现异步操作:asyncawait,这两个关键词要配合使用,如:

    loadData() async {
      String dataURL = "https://jsonplaceholder.typicode.com/posts";
      http.Response response = await http.get(dataURL);
      setState(() {
        widgets = json.decode(response.body);
      });
    }
    

    上面是一个典型的网络请求方法,使用async来表示loadData函数是一个异步操作,当运行到await代码时,表示有任务需要等待,CPU会去调度执行其他IO操作。过一段时间CPU通过事件循环会轮询一次,看某个协程是否任务已经处理完成,有返回结果可以被继续执行,如果可以被继续执行的话,则会沿着上次离开时指针指向的位置继续执行,也就是await标志的位置,执行后面的setState()刷新UI的操作;与iOS的异步操作有点类似。

    使用async会返回一个Future结果,Future也是Dart提供的一个关键词,可以通过链式调用,后面追加then来实现,如:

    Future.delayed(Duration(seconds: 1), (){
      int value = 10;
      return value;
    }).then((onValue){
      onValue++;
      print('value $onValue');
    });
    

    Dart提供了另一个对线程的实现方案:isolate,由线程和独立内存构成,isolate线程之间不共享内存,并且不和主线程的内存堆共享内存,因此不能访问主线程中的变量,或者使用 setState() 来更新 UI。isolate可以很好的利用多核CPU,来进行大量耗时任务的处理。isolate线程之间的通信主要通过port来进行,这个port消息传递的过程是异步的。通过Dart源码也可以看出,实例化一个isolate的过程包括,实例化isolate结构体、在堆中分配线程内存、配置port等过程。

    loadData() async {
      ReceivePort receivePort = ReceivePort();
      await Isolate.spawn(dataLoader, receivePort.sendPort);
    
      // The 'echo' isolate sends its SendPort as the first message
      SendPort sendPort = await receivePort.first;
    
      List msg = await sendReceive(sendPort, "https://jsonplaceholder.typicode.com/posts");
    
      setState(() {
        widgets = msg;
      });
    }
    
    // The entry point for the isolate
    static dataLoader(SendPort sendPort) async {
      // Open the ReceivePort for incoming messages.
      ReceivePort port = ReceivePort();
    
      // Notify any other isolates what port this isolate listens to.
      sendPort.send(port.sendPort);
    
      await for (var msg in port) {
        String data = msg[0];
        SendPort replyTo = msg[1];
    
        String dataURL = data;
        http.Response response = await http.get(dataURL);
        // Lots of JSON to parse
        replyTo.send(json.decode(response.body));
      }
    }
    
    Future sendReceive(SendPort port, msg) {
      ReceivePort response = ReceivePort();
      port.send([msg, response.sendPort]);
      return response.first;
    }
    

    好了,内容就到这里,以后有更多发现再来补充。若有问题,欢迎指正~
    希望与大家共勉!

    参考:
    https://flutterchina.club/flutter-for-ios/
    https://www.jianshu.com/p/54da18ed1a9e

    相关文章

      网友评论

          本文标题:Flutter怎么处理耗时操作?(异步和线程)

          本文链接:https://www.haomeiwen.com/subject/kdgvyltx.html