Dart 应用通常只会在单线程中处理它们的工作。并且在大多数情况中,这种模式不但简化了代码而且速度也够快.
但是,当你需要进行一个非常复杂的计算时,例如解析一个巨大的 JSON 文档。如果这项工作耗时超过了 16 毫秒,那么你的用户就会感受到掉帧。
为了避免掉帧,像上面那样消耗性能的计算就应该放在后台处理。在 Android 平台上,这意味着你需要在不同的线程中进行调度工作。而在 Flutter 中,你可以使用一个单独的 Isolate
Isolate
dart 代码只能使用同一个 Isolate 中的内容,Isolate 有自己的内存和事件循环机制;不同的 Isolate 是内存隔离的,这样因为Dart没有共享内存的并发,没有竞争的可能性所以不需要锁,也就不用担心死锁的问题。
因为Isolate之间没有内存共享,所以Isolate之间的通讯只能通过port进行。且消息的传递是异步的。
Isolate 的创建
Isolate 一般通过spawn / spawnUri来创建对象;
Isolate.spawn()
entryPoint 参数是必传的要在isolate中要调用的初始化函数,message是初始化函数要接收的信息。
external static Future<Isolate> spawn<T>(
void entryPoint(T message), T message,
{bool paused = false, // 暂停
bool errorsAreFatal = true, // 致命性错误
SendPort? onExit, // 退出时
SendPort? onError, // 发生错误时
@Since("2.3") String? debugName});
Isolate.spawnUri()
简单了解源码,spawnUri 需要三个必要参数,uri 为其他 Isolate 代码文件的路径;列表 args 为传递的参数列表,message 动态消息,一般是 SendPort;
external static Future<Isolate> spawnUri(
Uri uri,
List<String> args,
var message,
{bool paused = false,
SendPort? onExit,
SendPort? onError,
bool errorsAreFatal = true,
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});
例子:
import 'dart:async';
import 'dart:isolate';
int i = 0;
IntObject intobj = IntObject();
void main() async{
// 消息接收端口
final receive = ReceivePort(); //
receive.listen((message) { // 监听端口
print("main: Receive data : $message, i = $i , intobject = ${intobj.geti()}");
});
Isolate isolate = await Isolate.spawn(isolatefun, receive.sendPort); // 创建isolate,异步
}
// 初始化函数,接收一个SendPort 参数
void isolatefun(SendPort sendport){
int counter = 0 ;
// 定时器
Timer.periodic(Duration(seconds: 3),(_){
counter ++ ;
i++;
intobj.add();
String setMsg = "Notification data : $counter";
print("send message : $setMsg , i = $i , intobject = ${intobj.geti()}");
// 痛过端口发送信息
sendport.send(setMsg);
});
}
class IntObject {
int _i = 0;
add (){
_i++;
}
int geti(){
return _i;
}
}
运行结果:
可以看到我们在isolate 中的操作并没有影响到main()函数中关于i 和 intobj 的值。