【问题标题】:Isolate with FutureBuilder not working in Flutter隔离 FutureBuilder 在 Flutter 中不起作用
【发布时间】:2023-01-02 05:36:05
【问题描述】:

我正在尝试使用 FutureBuilder 加载一个大文件并使用以下代码进行隔离。


void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(const MyApp());
}

// utils
const fileName = 'assets/files/big_file.txt';
const smallFileName = 'assets/files/small_file.txt';
//
Future<String> loadBigFile(String fileName) async {
  return rootBundle.loadString(fileName);
}


Future<String> loadFileUsingThread(String fileName) async {
  return await compute(loadBigFile, fileName);
}

稍后当我尝试调用下面的内容时

Future<String>? _future;
_future = loadFileUsingThread(smallFileName);
            child: FutureBuilder<String>(
              initialData: '',
              future: loadFileUsingThread(smallFileName),
              builder: (context, snapshot) {
                if (snapshot.connectionState == ConnectionState.waiting) {
                  return const Center(child: CircularProgressIndicator());
                }
                if (snapshot.connectionState == ConnectionState.done &&
                    snapshot.hasData) {
                  return SingleChildScrollView(
                    child: Text(snapshot.data.toString()),
                  );
                }
                return Center(
                    child: Text(
                  'File Read Error ${snapshot.error}',
                ));
              },
            ),
          )

我收到以下错误

Unhandled Exception: Binding has not yet been initialized.
The "instance" getter on the ServicesBinding binding mixin is only available once that binding has been initialized.
Typically, this is done by calling "WidgetsFlutterBinding.ensureInitialized()" or "runApp()" (the latter calls the former). Typically this call is done in the "void main()" method. The "ensureInitialized" method is idempotent; calling it multiple times is not harmful. After calling that method, the "instance" getter will return the binding.
In a test, one can call "TestWidgetsFlutterBinding.ensureInitialized()" as the first line in the test's "main()" method to initialize the binding.
If ServicesBinding is a custom binding mixin, there must also be a custom binding class, like WidgetsFlutterBinding, but that mixes in the selected binding, and that is the class that must be constructed before using the "instance" getter.

【问题讨论】:

  • edit你的问题分享给你main()入口函数
  • 我无法重现。也许尝试重建应用程序...
  • 我做了一切。坚持了2天。

标签: flutter mobile dart-isolates


【解决方案1】:

rootBundle.loadStringimplementation使用isolate解码。我觉得没必要再用isolate了。

该函数期望存储的字符串是 UTF-8 编码的,因为 Utf8Codec 将用于解码字符串。如果字符串大于 50 KB,则解码过程将委托给一个 isolate 以避免主线程出现卡顿。

Future<String> loadString(String key, { bool cache = true }) async {
  final ByteData data = await load(key);
  if (data == null) {
    throw FlutterError('Unable to load asset: $key');
  }
  // 50 KB of data should take 2-3 ms to parse on a Moto G4, and about 400 μs
  // on a Pixel 4.
  if (data.lengthInBytes < 50 * 1024) {
    return utf8.decode(data.buffer.asUint8List());
  }
  // For strings larger than 50 KB, run the computation in an isolate to
  // avoid causing main thread jank.
  return compute(_utf8decode, data, debugLabel: 'UTF8 decode for "$key"');
}

【讨论】:

    猜你喜欢
    • 2021-05-11
    • 1970-01-01
    • 2021-11-26
    • 1970-01-01
    • 2019-11-03
    • 2021-11-23
    • 2021-06-28
    • 2014-03-06
    • 1970-01-01
    相关资源
    最近更新 更多