文章目录
前言
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就很类似了,可以当成异步的另一种选择。