Flutter 简化线程Isolate的使用

文章目录


前言

flutter的线程是数据独立的,每个线程一般通过sendport来传输数据,这样使得线程调用没那么方便,本文将提供一种支持lambda启动isolate的方法,且支持捕获值类型变量,以及支持返回值。


一、完整代码

由于代码量较少,原理就不介绍了,直接给出完整实现。

isolate_helper.dart

dart 复制代码
///在隔离中执行任务,只能捕获值,不能捕获引用或指针。
///需要注意成员方法中调用传lambda会自动捕获this,this中包含引用类型则不行,此时可修改为static方法中调用。
Future<T> isolateFuture<T>(T Function() isolateEntry) async {
  ReceivePort receivePort = ReceivePort();
  //创建一个Isolate相当于创建一个子线程
  await Isolate.spawn((message) {
    message.sendPort.send(message.isolateEntry());
  }, _IsolateMessage(isolateEntry, receivePort.sendPort));
  var ret = await receivePort.first as T;
  return ret;
}

class _IsolateMessage<T> {
  T Function() isolateEntry;
  SendPort sendPort;
  _IsolateMessage(this.isolateEntry, this.sendPort);
}

二、使用示例

1、通过lambda启动线程

dart 复制代码
void test() {
  String a = "hello word!";
  isolateFuture(() {
    //在子线程中执行任务,捕获(拷贝)了变量a。
    print("${Isolate.current.hashCode} $a");
  });
  print("${Isolate.current.hashCode} $a");
}

2、获取线程返回值

dart 复制代码
Future test1() async {
  String a = await isolateFuture(() {
    //在子线程中执行任务:略
    //返回结果
    return "hello word!";
  });
  print(a);
}

3、线程通信

dart 复制代码
void test2() {
  ReceivePort mainReceivePort = ReceivePort();
  SendPort isolateSendPort;
  mainReceivePort.listen((message) {
    //监听子线程的消息
    switch (message[0]) {
      case 0:
        print(message[1]);
        break;
      case 1:
        isolateSendPort = message[1];
        isolateSendPort.send([0, "hello word!"]);
        break;
    }
  });
  //sendport是可以直接捕获传给isolate的。
  final mainSendPort = mainReceivePort.sendPort;
  isolateFuture(() {
    //发送消息给主线程
    mainSendPort.send([0, "hello word!"]);
    ReceivePort isolateReceivePort = ReceivePort();
    isolateReceivePort.listen((message) {
      //监听主线程的消息
      switch (message[0]) {
        case 0:
          print(message[1]);
          break;
      }
    });
    //将sendPort发送到主线程,建立双向通信
    mainSendPort.send([1, isolateReceivePort.sendPort]);
  });
}

4、结束isolate

dart 复制代码
Future test1() async {
  String a = await isolateFuture(() {
    //isolate结束时建议手动kill,即此方法返回后isolate并不会结束,所以支持异步操作。返回后没有任何操作了gc似乎会清理isolate。
    Isolate.current.kill();
    return "hello word!";
  });
  print(a);
}

总结

以上就是今天要讲的内容,本文的提供线程启动方法,很大程度方便了使用,尤其是支持lambda,可以在任意上下文捕获变量开启线程,执行任务,并获取返回值,用法和Future就很类似了,可以当成异步的另一种选择。

相关推荐
励志的小陈4 小时前
贪吃蛇(C语言实现,API)
c语言·开发语言
Makoto_Kimur4 小时前
java开发面试-AI Coding速成
java·开发语言
laowangpython4 小时前
Gurobi求解器Matlab安装配置教程
开发语言·其他·matlab
wengqidaifeng4 小时前
python启航:1.基础语法知识
开发语言·python
观北海4 小时前
Windows 平台 Python 极简 ORB-SLAM3 Demo,从零实现实时视觉定位
开发语言·python·动态规划
jiejiejiejie_6 小时前
Flutter 三方库 pull_to_refresh 的鸿蒙化适配指南
flutter·华为·harmonyos
Ulyanov6 小时前
《PySide6 GUI开发指南:QML核心与实践》 第二篇:QML语法精要——构建声明式UI的基础
java·开发语言·javascript·python·ui·gui·雷达电子对抗系统仿真
码界筑梦坊6 小时前
357-基于Java的大型商场应急预案管理系统
java·开发语言·毕业设计·知识分享
anzhxu6 小时前
Go基础之环境搭建
开发语言·后端·golang
yu85939587 小时前
基于MATLAB的随机振动仿真与分析完整实现
开发语言·matlab