flutter - FutureBuilder 使我的应用程序卡住,因为它在构建之前等待文件加载

标签 flutter dart future

我正在编写一个非常基本的 Flutter 应用程序来阅读公共(public)领域的书籍。我在我的应用程序 Assets 中包含了一个包含一本书的 .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 意味着调用可能会被委托(delegate)给稍后的时间(取决于您如何安排它),但它仍然在同一个线程中运行。

你想要做的是使用 Isolate ,并在其中读取文件。一旦你有了文件(并进行了你需要做的任何处理),你应该能够将它传回 Text 类并且它应该更快 - 尽管如果你正在处理非常大量的文本它可能仍然由于 Text 类仍然需要处理所有文本,所以有点卡顿。如果确实断断续续,我建议将文本分成几部分(章节/段落?)并使用多个文本和/或富文本对象将其显示在列表中。

在 flutter 中使用隔离的最简单方法是 `compute' function .

那么你的 future 就会有这样的东西:

await compute(readFile, <path to file>);

请注意,compute 的输入和输出有一些限制,因为它使用了 Isolate's SendPort。引擎盖下:

The content of message can be: primitive values (null, num, bool, double, String), instances of SendPort, and lists and maps whose elements are any of these. List and maps are also allowed to be cyclic.

关于flutter - FutureBuilder 使我的应用程序卡住,因为它在构建之前等待文件加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56484082/

相关文章:

android - 为 Android 构建 libflutter_rust_bridge_example 时出现 Flutter 错误 : Failed to load dynamic library 'libflutter_rust_bridge_example.so'

dart - Flutter 在一个条件下关闭一个对话框

eclipse - 编写Dart构建脚本= builder.dart

Python asyncio、futures 和 yield from

Dart 多个构造函数

google-cloud-firestore - 如何使用 Cloud Function 和 Flutter 从新图像中获取 URL?

flutter - 我如何在 flutter 中进行第二排序

android - Flutter Android后退按钮导航回主页

java - 使用 ExecutorService 观察 Future<T> 对象的完成情况

rust - 有没有办法在新线程上启动 tokio::Delay 以允许主循环继续?