Flutter: необработанное исключение: доступ к ServicesBinding.defaultBinaryMessenger был осуществлен до инициализации привязки

134

Любое решение этой проблемы?

Трассировки стека:

[VERBOSE-2:ui_dart_state.cc(148)] Unhandled Exception: ServicesBinding.defaultBinaryMessenger was accessed before the binding was initialized.
If you're running an application and need to access the binary messenger before `runApp()` has been called (for example, during plugin initialization), then you need to explicitly call the `WidgetsFlutterBinding.ensureInitialized()` first.
If you're running a test, you can call the `TestWidgetsFlutterBinding.ensureInitialized()` as the first line in your test's `main()` method to initialize the binding.
#0      defaultBinaryMessenger.<anonymous closure> (package:flutter/src/services/binary_messenger.dart:73:7)
#1      defaultBinaryMessenger (package:flutter/src/services/binary_messenger.dart:86:4)
#2      MethodChannel.binaryMessenger (package:flutter/src/services/platform_channel.dart:140:62)
#3      MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:314:35)
<asynchronous suspension>
#4      MethodChannel.invokeMapMethod (package:f<>
Sopheadavid Sopheap
источник
поместите эту строку в качестве первого оператора в main () - WidgetsFlutterBinding.ensureInitialized ();
Виджай Рам,

Ответы:

314

Эта проблема возникает при обновлении Flutter. Причина в том, что вы ждете каких-то данных или запускаете asyncвнутри функцию main().

Я инициализировал ScopedModelвнутри, main()а внутри я ждал некоторых данных.

Есть очень небольшое исправление. Просто беги WidgetsFlutterBinding.ensureInitialized()внутрь void main(), прежде чем это сделаешь runApp(). Работает как шарм !!

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(Delta(
    model: ProductDataModel(),
  ));
}
Дебасмита Саркар
источник
17
убедитесь, что WidgetFlutterBinding.ensureInitialized () - это первая строка main (). а затем продолжайте как обычно
Авниш Кумар
10
Каковы возможные негативные последствия этого? Должны ли все приложения flutter иметь эту строку в начале main()метода?
user482594
3
Если вы используете метод async в main (), вам нужно добавить это
Дебасмита Саркар
2
не работает для v1.14.4 / v1.14.6 break на var databasesPath = await getDatabasesPath ();
Ares91,
70

Обычно это происходит, если вы ожидаете main()метода. Итак, решение было бы таким:

void main() {
  // add this, and it should be the first line in main method
  WidgetsFlutterBinding.ensureInitialized(); 

  // rest of your app code
  runApp(
    MaterialApp(...),
  );
}
CopsOnRoad
источник
1
не работает - обрывается при соединении (await getDatabasesPath (), 'mydb.db'),
live-love
25

Не уверен, что у меня правильный ответ, но я получил ту же ошибку после недавнего обновления флаттера, и мне удалось заставить его работать, поэтому я делюсь своими выводами.

Похоже, ошибка может быть вызвана недавним критическим изменением: https://groups.google.com/forum/#!msg/flutter-announce/sHAL2fBtJ1Y/mGjrKH3dEwAJ .

В результате нам нужно вручную изменить код следующим образом:

  • Если вы запускаете приложение и вам нужно получить доступ к бинарному мессенджеру до того, как runApp()он был вызван (например, во время инициализации плагина), вам необходимо явно вызвать WidgetsFlutterBinding.ensureInitialized()первый.
  • Если вы запускаете тест, вы можете вызвать в TestWidgetsFlutterBinding.ensureInitialized()качестве первой строки в main()методе вашего теста для инициализации привязки.

В качестве альтернативы, если вы новичок, как я, и изо всех сил пытаетесь понять вышесказанное и # 38464 , вы можете временно избежать этой проблемы, переключившись на бета-канал. Просто запустите бета-версию флаттер-канала. Критическое изменение еще не находится в бета-канале, поэтому после перехода на бета-канал вы не получите эту ошибку, по крайней мере, сейчас.

Марс
источник
Спасибо, братан, теперь я просто использовал бета-версию, чтобы избежать ошибки!
Sopheadavid Sopheap
11

просто добавьте эту строку в main.dart

WidgetsFlutterBinding.ensureInitialized(); 

ваш код выглядит как

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  return runApp(MultiProvider(
    providers: [
      ChangeNotifierProvider.value(
        value: AppState(),
      )
    ],
    child: MyApp(),
  ));
}
Саад Ахмед
источник
2

в моем случае при использовании ориентации

до решения:

void main() {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]).then((_).{
runApp(MyApp());
});
}

решено использовать:

void main() {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
  .then((_) {
runApp(MyApp());
});
}

Дело в том, чтобы добавить WidgetsFlutterBinding.ensureInitialized () в первую строку основного класса.

арджава
источник
2

Вы можете столкнуться с этим, если пытаетесь выполнить собственный код плагина в изолированном режиме. Здесь это хорошо объясняется в документации isolate_handler :

Плагины используют механизм, называемый каналом платформы, для связи между Dart и собственными сторонами, механизм передачи сообщений с использованием типа MethodChannel. Этот механизм зависит от элементов базового движка пользовательского интерфейса для работы.

Уловка здесь в том, что изоляты обеспечат прирост производительности только в случае дорогостоящего в вычислительном отношении кода дротика. Код платформы плагина снова будет использовать основной поток (UI).

Вызов WidgetsFlutterBinding.ensureInitializedвнутри изолята также не удастся из-за отсутствия базового движка пользовательского интерфейса в изоляте.

sjsam
источник
1

Раньше у меня была версия v1.12.13+hotfix.5, потом я перешел на версию, v1.14.4и она работала.

Ошибка говорит, что вы должны добавить WidgetsFlutterBinding.ensureInitialized();, но поскольку это не сработало для меня, я переключился на другую версию. Однако следует иметь в виду, что вам все равно нужно добавить WidgetsFlutterBinding.ensureInitialized();первую строку в своем main!

hanslissi
источник
1

Решение: вызовите WidgetsFlutterBinding.ensureInitialized(); перед вызовом асинхронных функций.


void main() async {
  WidgetsFlutterBinding.ensureInitialized();   //  ADD THIS BEFORE YOUR ASYNC FUNCTION CALL.
  await Firestore.instance.settings(...);      //  NOW YOU CAN CALL ASYNC FUNCTION.   
  ...
  runApp(
    ...
  )
JesusIniesta
источник
0

Ответ, опубликованный на вопрос 47033 GitHub, решил мою проблему.

проблема: https://github.com/flutter/flutter/issues/47033

решение, которое сработало для меня: https://github.com/flutter/flutter/issues/47033#issuecomment-571936089

Я думаю, что это проблема, связанная с версией флаттера 1.12.13 + исправление, возможно, понижение версии флаттера также может помочь.

Ачинта Исуру
источник