Flutter:当 运行 函数使用 isolates 时,在二进制信使初始化之前无法使用此 MethodChannel

Flutter: Cannot use this MethodChannel before the binary messenger has been initialized when running a function using isolates

我正在尝试在我的 Flutter 应用程序中使用 isolates 和 Bloc 作为状态管理解决方案。现在,当 运行 wallet_list.dart.

中的特定函数时,我 运行 出错了
// wallet_list.dart
final FlutterSecureStorage _storage = const FlutterSecureStorage();

FutureOr<List<alan.Wallet>> getWalletList(int value) async {
  Map<String, String> allValues = await _storage.readAll();
  final List<alan.Wallet> _walletList = [];

  allValues.forEach((key, value) {
    if (key.startsWith(WalletOverviewHomeScreen.walletKey)) {
      final arrMnemonic = value.split(' ');
      final _wallet = alan.Wallet.derive(arrMnemonic, certikNetworkInfo);
      // debugPrint('Adding wallet: $_wallet');
      _walletList.add(_wallet);
    }
  });

cubitclassWalletInitializationCubit.

中的方法之一使用了以下函数
// inside WalletInitializationCubit
Future<void> getWalletListAndDefaultWallet() async {
    try {
      debugPrint('WalletListInitialization');
      emit(WalletInitializationLoading());
      final List<alan.Wallet> walletList = await compute(
        getWalletList,
        1
      );

      // other cubit logic
  }

尝试构建应用程序时,returns出现此错误:

Exception has occurred.
_AssertionError ('package:flutter/src/services/platform_channel.dart': Failed assertion: 
line 134 pos 7: '_binaryMessenger != null || ServicesBinding.instance != null': Cannot use 
this MethodChannel before the binary messenger has been initialized. This happens when you 
invoke platform methods before the WidgetsFlutterBinding has been initialized. You can fix 
this by either calling WidgetsFlutterBinding.ensureInitialized() before this or by passing
a custom BinaryMessenger instance to MethodChannel().)

对于上下文,main.dart 文件看起来与此类似。

void main() async {
  runApp(
    const MyApp(),
  );
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  const MyApp();

  @override
  Widget build(BuildContext context) {
    final ThemeData theme = ThemeData();
    return MultiBlocProvider(
      providers: [
        BlocProvider<WalletInitializationCubit>(
          create: (context) => WalletInitializationCubit(),
        ), 
      ],
      child: HomeScreen(),
      .....
  }
}

导致错误的相关代码行是

// in getWalletList function
Map<String, String> allValues = await _storage.readAll();

我试过在该行之前添加 WidgetsFlutterBinding.ensureInitialized()

// in getWalletList function
WidgetsFlutterBinding.ensureInitialized()
Map<String, String> allValues = await _storage.readAll();

但这会导致 UI actions are only available on root isolate 错误。

我该如何解决这个错误?我不能使用 asyncawait 的通常方式,因为 运行 的过程相当繁重并导致应用程序冻结。

根据错误 UI actions are only available on root isolate,很明显您无法在隔离区内执行 WidgetsFlutterBinding.ensureInitialized()。另外,正如您在评论中提到的,_storage.readAll() 方法会导致此问题。

考虑到这一点,您可以做的是 运行 主隔离中的 _storage.readAll()(主函数的 运行 是什么)并将结果传递给隔离作为一个参数。