flutter - Flutter - 如何在不阻塞 UI 的情况下计算包含未来的繁重任务?
问题描述
我正在创建一个以 json 格式从 Internet 获取帖子的应用程序。我使用工厂将 json 解析为 Flutter 中的 Post 对象。Post 对象包括标题、正文和图像。我使用列表视图构建器在列表视图中显示这些帖子。繁重的任务是我从图像中计算出 2 种主色以设置为帖子项目的背景渐变。为此,我使用:https ://pub.dartlang.org/packages/palette_generator
我计算了 json 解析器工厂中的 2 种主色,因为这样我就有了一个完整的 Post 对象,其中包含所有需要的信息。同样这样我就不必在渲染 Post 对象时计算颜色。我使用以下代码执行此操作:
Future<List> _getColors() async {
Color gradientOne, gradientTwo;
String imageUrl = json['image'];
paletteGenerator = await PaletteGenerator.fromImageProvider(
CachedNetworkImageProvider(imageUrl));
gradientOne = paletteGenerator.colors.toList()[0];
gradientTwo = paletteGenerator.colors.toList()[1];
return [gradientOne, gradientTwo];
}
我将它添加到 Post 对象并在渲染中等待这个未来:
post.gradientColors
.then((result) => {
gradient = result,
this.setState(() {
loading = false;
})
})
在主 UI 中,我会显示一个加载指示器,直到解决所有期货。为此,我使用以下代码:
List<Future> futures = [];
for (var post in tmpList) {
futures.add(post.gradientColors);
}
await Future.wait(futures)
.then((result) => {list.addAll(tmpList)});
}
除了获取新帖子时 UI 滞后外,这可以正常工作。经过一番阅读,我发现我可以在 Flutter 中使用 Isolates。所以我改变了我的解析功能,如下所述:https ://flutter.io/docs/cookbook/networking/background-parsing
这完美无瑕,我的应用程序运行没有任何延迟,缺点是我的颜色没有计算。出于某种原因,当我使用 compute() 时,我的 Future 永远不会得到结果。
在这种情况下是否可以使用计算,或者是否有更好的方法来计算颜色而不会导致我的 UI 滞后?
编辑
我尝试在没有计算的情况下对 Isolate 进行编程,但颜色期货仍然无法加载。这是我使用的代码:
ReceivePort receivePort = ReceivePort();
Isolate isolate = await Isolate.spawn(getMorePosts, receivePort.sendPort);
receivePort.listen((data) {
list.addAll(data);
});
我确实收到了所有数据,但我的未来再次没有完成。
解决方案
不幸的是compute()
只支持同步结果。
compute()
很简单,只是一个包装器,可以更容易地启动隔离。
您可以使用自定义代码启动额外的隔离并获得更多功能。
https://api.dartlang.org/stable/2.1.1/dart-isolate/dart-isolate-library.html
隔离包提供了一些方便的功能,使使用隔离更容易。
推荐阅读
- c# - EF 选择与实体有一个字段不同的记录
- android - AdMob 横幅未显示
- javascript - 比较具有 null 值和空字符串的 JS 对象
- regex - 查找/替换正则表达式以重新排列 Notepad++ 中的文本
- asp.net-core - 在 Razor Pages 中,如何正确地将 asp-for 标签助手与对象一起使用?
- laravel - laravel 政策未调用
- google-analytics - 在 Google 分析中获得读取和分析权限
- javascript - Javascript:动态呈现列表 [初学者]
- javascript - 将颜色更改为 SVG id
- java - 关闭ApplicationContext仍然没有关闭springboot应用