• 注册
  • Android博客 Android博客 关注:0 内容:1123

    【Flutter 专题】92 图解 Dart 单线程实现异步处理之 Isolate (一)

  • 查看作者
  • 打赏作者
  • 当前位置: 职业司 > Android开发 > Android博客 > 正文
    • Android博客
    • 分享达人

            小菜刚尝试了 Futureasync-await 实现的简单异步操作,但对于耗时较长的异步该如何处理呢?对于 Android 来说可以新开一个线程单独处理,而对应的 Dart 可以用 Isolate 来处理;

      Isolate

            Isolate 是对 Dart 并发模式的实现,类似于 Android 中的 Thread 线程,但与 Thread 有本质的区别,Thread 可以实现内存共享,而 Isolate 不能;

            所有的 Dart Code 都是在 Isolate 中执行的,代码只能使用同一个 Isolate 中的内容,Isolate 有自己的内存和事件循环机制;不同的 Isolate 是内存隔离的,因此只能通过 Port 机制发送消息通信,其原理是向不同的 Isolate 队列中执行写任务;

      Isolate 的创建

            Isolate 一般通过 spawn / spawnUri 来创建对象;

      Isolate.spawn()
      external static Future<Isolate> spawn<T>(
      void entryPoint(T message), T message,
      {bool paused: false,
      bool errorsAreFatal,
      SendPort onExit,
      SendPort onError,
      @Since("2.3") String debugName});
      复制代码

            简单了解源码,spawn 必须的参数包括需要耗时操作的 entryPointT 任意类型的 message 数据,即 Isolate 中可以传递任意类型的数据;

      _loadIsolateDate() async {
      await Isolate.spawn(_backgroundWork, ReceivePort().sendPort);
      }
      static _backgroundWork(SendPort sendPort) {
      sendPort.send('BackgroundWork -> currentTime -> ${DateTime.now().millisecondsSinceEpoch}');
      }
      复制代码
      Isolate.spawnUri()
      external static Future<Isolate> spawnUri(
      Uri uri,
      List<String> args,
      var message,
      {bool paused: false,
      SendPort onExit,
      SendPort onError,
      bool errorsAreFatal,
      bool checked,
      Map<String, String> environment,
      @Deprecated('The packages/ dir is not supported in Dart 2')
      Uri packageRoot,
      Uri packageConfig,
      bool automaticPackageResolution: false,
      @Since("2.3")
      String debugName});
      复制代码

            简单了解源码,spawnUri 需要三个必要参数,uri 为其他 Isolate 代码文件的路径;列表 args 为传递的参数列表,message 动态消息,一般是 SendPort

      _loadIsolateDate03() async {
      ReceivePort receivePort = ReceivePort();
      await Isolate.spawnUri(new Uri(path: "./utils/second_isolate.dart"),
      ['params01, params02, params03'], receivePort.sendPort);
      receivePort.listen((val) => print('listen -> 【$val】'));
      }
      复制代码

      Isolate 的通讯

            Isolate 可以方便的利用多核 CPU 来处理耗时操作,因内存不共享,需要通过 Port 进行消息通讯;其中 Port 消息传递也是异步的;

      单向通讯

            Port 一般是成对出现,分别是 ReceivePort 接收端口和 SendPort 发送端口;而 ReceivePort 也可以生成自己的 SendPort;只需要把 SendPort 传递给其他 Isolate 即可;

      _loadIsolateDate01() async {
      ReceivePort receivePort = ReceivePort();
      await Isolate.spawn(_backgroundWork, receivePort.sendPort);
      receivePort.listen((val) => print('listen -> 【$val】'));
      }
      static _backgroundWork(SendPort sendPort) async {
      sendPort.send(
      'BackgroundWork -> currentTime -> ${DateTime.now().millisecondsSinceEpoch}');
      Future.delayed(Duration(seconds: 3), () {
      return sendPort.send(
      'BackgroundWork delayed 3s -> currentTime -> ${DateTime.now().millisecondsSinceEpoch}');
      });
      }
      复制代码

      【Flutter 专题】92 图解 Dart 单线程实现异步处理之 Isolate (一)

      双向通讯

            双向通讯与单向通讯一样,把双方的 SendPort 相互传递即可;

      _loadIsolateDate02() async {
      ReceivePort receivePort = ReceivePort();
      var sendPort;
      await Isolate.spawn(_backgroundWork2, receivePort.sendPort);
      receivePort.listen((val) {
      if (val is SendPort) {
      sendPort = val as SendPort;
      print("双向通讯建立成功");
      }
      print("Isolate Recevie Data -> 【$val】");
      if (sendPort != null) {
      sendPort.send('_loadIsolateDate02 -> currentTime -> ${DateTime.now().millisecondsSinceEpoch}');
      }
      });
      }
      static _backgroundWork2(SendPort sendPort) async {
      ReceivePort receivePort = new ReceivePort();
      receivePort.listen((val) {
      print("Background Isolate Receive Data -> 【$val]");
      });
      sendPort.send('BackgroundWork -> currentTime -> ${DateTime.now().millisecondsSinceEpoch}');
      sendPort.send(receivePort.sendPort);
      Future.delayed(Duration(seconds: 2), () {
      return sendPort.send('BackgroundWork delayed 2s -> currentTime -> ${DateTime.now().millisecondsSinceEpoch}');
      });
      Future.delayed(Duration(seconds: 5), () {
      return sendPort.send(receivePort.sendPort);
      });
      }
      复制代码

      【Flutter 专题】92 图解 Dart 单线程实现异步处理之 Isolate (一)

      Isolate 的销毁

            Isolate 就像机器中的一个小空间,有自己的内存块,因此在使用 Isolate 结束后应及时关闭并销毁当前 Isolate

      isolate.kill(priority: Isolate.immediate);
      复制代码

      Tips

      Q:Invalid argument(s): Isolate.spawn expects to be passed a static or top-level function

            小菜刚开始创建 Isolate 时,遇到如下错误;

      【Flutter 专题】92 图解 Dart 单线程实现异步处理之 Isolate (一)

      A:

            需要将 Isolate.spawn 中的 message 参数方法设置成 static 方法或放置在 main() 入口;


            由于篇幅和测试案例不足,小菜分为两篇小博客对 Isolate 进行学习,对异步的认知还不够深入;如有错误请多多指导!

      来源: 阿策小和尚

      请登录之后再进行评论

      登录

      手机阅读天地(APP)

      • 微信公众号
      • 微信小程序
      • 安卓APP
      手机浏览,惊喜多多
      匿名树洞,说我想说!
      问答悬赏,VIP可见!
      密码可见,回复可见!
      即时聊天、群聊互动!
      宠物孵化,赠送礼物!
      动态像框,专属头衔!
      挑战/抽奖,金币送不停!
      赶紧体会下,不会让你失望!
    • 实时动态
    • 签到
    • 做任务
    • 发表内容
    • 偏好设置
    • 到底部
    • 帖子间隔 侧栏位置:
    • 还没有账号?点这里立即注册