在用flutter写IM的时候,当用户很久没有上线过,再次上线的时候,会收到很多离线消息。我是用一个while循环收的,直到收完离线消息,这样可想而知,一点会影响UI的。 消息不多的情况还好,当消息多的时候必然会阻塞UI.

于是这样的任务必须放到子线程去做。而dart中多线程的实现是isolate的方式实现的。在flutter中对Isolate有一定的封装,使用compute, 下面我就用这两种方式各实现一个demo.

  1. isolate的方式, 通讯是用ReceivePort与SendPort,一个用于发消息,一个用于收消息
import 'dart:async';
import 'dart:isolate';
import 'package:http/http.dart' as http;

main() async {
  ReceivePort receivePort = ReceivePort();
  await Isolate.spawn(echo, receivePort.sendPort);

  // 'echo'发送的第一个message,是它的SendPort
  SendPort sendPort = (await receivePort.first) as SendPort;

  var msg = await sendReceive(sendPort, "test1");
  print('received $msg');
  msg = await sendReceive(sendPort, "test2");
  print('received $msg');
}

// 新isolate的入口函数, 该函数必须是static或全局函数,该函数不能访问主线程中的变量,只能通过ReceivePort与SendPort将数据传递过去。
echo(SendPort sendPort) async {
  // 实例化一个ReceivePort 以接收消息
  var port = new ReceivePort();

  // 把它的sendPort发送给宿主isolate,以便宿主可以给它发送消息
  sendPort.send(port.sendPort);

  // 监听消息
  await for (var msg in port) {
    String data = msg[0] as String;
    SendPort replyTo = msg[1] as SendPort;

//在此ioslate中处理,并将结果发给宿主,这里将数据原封不动返回
    String result = data ;
    replyTo.send(result );
    if (data == "test2") port.close();
  }
}

/// 对某个port发送消息,并接收结果
Future sendReceive(SendPort port, msg) {
  ReceivePort response = new ReceivePort();
 //发送消息数据给echo isolate
  port.send([msg, response.sendPort]);
//response.first即为从echo isolate接收到的数据
  return response.first;
}

上面代码的大意是,开启一个线程,然后主线程发送字符串给子线程,子线程再将字符串原封不懂的发送给主线程。这里主线程每发送一个字符串的时候都需要创建ReceivePort,可以只用一个ReceivePort然后用listen来接收数据

receivePort.listen((value){
});
  1. compute
function callback( val ) {
  ...
  return res
}
/// `callback` 必须是全局方法或者是类的静态方法
var res = await compute( callback , val );

compute第二个参数就是传递给线程的参数。

需要多线程的朋友,赶快试一试吧。

Logo

智屏生态联盟致力于大屏生态发展,利用大屏快应用技术降低开发者开发、发布大屏应用门槛

更多推荐