在c++中Thread可以通过SendMessage和UI通信,达到更新ui的目的。
flutter也有对应的方式,ReceivPort()
ReceivPort()
比如在线程中和ui进行频繁通信,比如一个计算量超级大的方法,你需要把每个计算进度都返回给ui并显示出来。这是ReceivePort就要出场了,可以用在isolate和compute,可以把它想象成websocket,是可以双向通信的,只需要建立ReceivePort()就行了。
isolate和compute区别
isolate不直接返回结果,需要双向通信来获知结果,可以长时间运行
compute结束后会返回结果,比较适合单向通信,一次性任务
详解
1、【UI】创建接收端口,recvPort是可以进行listen的
var recvPort = ReceivePort();
2、【UI】监听listen后就能接收线程消息了
recvPort.listen((msg){ });//接收线程消息
3、【UI】创建线程时候,把接收端口的另一端(recvPort.sendPort)发给线程
compute(func,recvPort.sendPort)
4、【Thread】线程中就可以通过sendPort发消息外ui了
sendPort.send('hello')
简单例子
class MyData{
SendPort sendPort;
int n;
MyData(this.sendPort,this.n);
}
//耗时的计算方法
int go(MyData data){
print('data.n:${data.n}');
for(int i=0;i<10;i++){
sleep(Duration(seconds:1));
//发送百分比
data.sendPort.send({'progress':'hello world,progress:$i %'});
}
//上面实现了单向通信:线程发送msg给外面。
//如果要双向通信,接收外部命令:
//1、创建接收端口
//var recvPort = ReceivePort();
//2、把接收端口的另一端发给外面
//data.sendPort.send({'recv_port':recvPort.sendPort});
//3、listen后就能接受外部指令了
//recvPort.listen((command){});//接收外部指令
return 1;
}
}
onTap() async{
var recvPort = ReceivePort();
var data = MyData(recvPort.sendPort,123);
//监听返回消息
recvPort.listen((message) {
print('recvPort.listen:${message}');
//listen里面是可以setState更新ui的
setState(()=>_message = message);
});
//Isolate开启线程
await Isolate.spawn(go,data);
//也可以用compute
//await Isolate.compute(go,data);
/*
//ps:如果go是一个非静态方法,可以这样执行
await Isolate.spawn((data){
go(data);
},data);
*/
return;
}
网友评论