我正在开发一个捕获和处理图像的应用程序。代码的简化版本是:
build() {
return FloatingActionButton(
onPressed: processImage,
child: Icon(
Icons.camera_alt,
color: color,
),
);
}
processImage(Camera image) async {
await image.process();
}
在另一堂课上:
Future<image> process() {
return Future(() {
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
//process image
}
}
});
}
但当process()
运行时,UI 冻结。
为什么会发生这种情况?该函数不是传递给在后台运行的 Future 构造函数吗?
由于 Dart 使用事件循环,因此所有代码(同步和异步)将简单地在同一事件循环上运行isolate
(think thread
在其他语言中作为类比),只是在不同的时间点。因此,当你的process
方法出队并执行,尽管是异步的,但它会阻塞线程并由于执行时间较长而导致丢帧。该问题的最佳解决方案是在新线程中生成另一个隔离,并在那里执行计算。 Flutter 为这个确切的用例提供了一种方便的方法,称为compute https://api.flutter.dev/flutter/foundation/compute.html。它需要一个顶级函数(不在类中,也不是匿名函数),该函数可以具有基本类型参数(包括Map
and List
) 作为一个参数,并将在将来的某个时刻返回。欲了解更多信息compute
,请参阅上面链接的文档。
如果您需要传递多个参数compute
,一个常见的模式(除了这个用例之外)是创建一个将类的字段序列化为Map<String, dynamic>
,以及一个从 a 创建对象的工厂构造函数Map<String, dynamic>
。如果使用反射,这个过程会更容易,但 Flutter 由于性能原因禁用了它。
有关完整示例compute
来自 Flutter 文档,请参见此处:https://flutter.dev/docs/cookbook/networking/background-parsing https://flutter.dev/docs/cookbook/networking/background-parsing
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)