我正在编写一个非常基本的 flutter 应用程序,用于阅读公共领域的书籍。我在应用程序的资产中包含了一个包含一本书的 .txt 文件。因为一本书很长并且需要时间来加载,所以我尝试使用 FutureBuilder,它会在加载书籍时显示圆形进度指示器,但是,当我单击按钮打开书籍时,应用程序会冻结,直到书籍已加载,而不是按照我的意愿转换到图书页面并在加载图书时显示进度指示器。
我检查了一个较小的文件,它没有冻结。我试图告诉 FutureBuilder 显示进度指示器,但它并没有冻结。
FutureBuilder(
future: text, //Future<String>
builder: (context,snapshot) {
if (snapshot.connectionState==ConnectionState.done) {
return Text(
snapshot.data,
style: TextStyle(fontSize: 20),);
}
else {
return CircularProgressIndicator();
}
},
)
看起来 FutureBuilder 只是尝试使用文本进行构建,而不是在没有文本的情况下进行构建,然后像应该做的那样稍后添加它。我如何告诉它这样做?
Dart 大多是单线程的。因此,当您阅读文本时,它是在与 UI 相同的线程中执行的,这就是它减慢速度的原因。使用 future 意味着调用可以委托给稍后的时间(取决于您如何安排它),但它仍然在同一个线程中运行。
你想做的是使用Isolate https://api.dartlang.org/stable/2.3.1/dart-isolate/dart-isolate-library.html,并在其中读取文件。一旦你有了文件(并做了任何你需要做的处理),你应该能够将它传递回 Text 类,并且它应该更快 - 尽管如果你正在处理大量的文本,它可能仍然有点口吃,因为 Text 类仍然需要处理所有文本。如果确实出现卡顿,我建议将文本分成几部分(章节/段落?)并使用多个文本和/或富文本对象将其显示在列表中。
在 flutter 中使用 Isolate 最简单的方法是‘计算’函数 https://api.flutter.dev/flutter/foundation/compute.html.
那么你的未来将会是这样的:
await compute(readFile, <path to file>);
请注意,输入和输出compute
有一些限制,因为它使用隔离的发送端口 https://api.flutter.dev/flutter/dart-isolate/SendPort/send.html在引擎盖下:
消息的内容可以是:原始值(null、num、bool、double、String)、SendPort 的实例以及其元素为其中任何一个的列表和映射。列表和映射也允许是循环的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)