Flutter: Unhandled Exception: ServicesBinding.defaultBinaryMessenger był dostępny przed zainicjowaniem powiązania


134

Jakieś rozwiązanie tego problemu?

Ślad stosu:

[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<>

umieść tę linię jako pierwszą instrukcję w main () - WidgetsFlutterBinding.ensureInitialized ();
Vijay Ram

Odpowiedzi:


312

Ten problem pojawia się po ulepszeniu Fluttera. Powodem tego jest to, że czekasz na jakieś dane lub uruchamiasz asyncfunkcję w środku main().

Inicjowałem się ScopedModelwewnątrz main()i wewnątrz, czekając na jakieś dane.

Jest bardzo mała poprawka. Po prostu wbiegnij do WidgetsFlutterBinding.ensureInitialized()środka void main(), zanim to zrobisz runApp(). Działa jak marzenie!!

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(Delta(
    model: ProductDataModel(),
  ));
}

17
upewnij się, że WidgetFlutterBinding.ensureInitialized () jest pierwszym wierszem funkcji main (). a następnie postępuj jak zwykle
Avnish kumar

10
Jaki jest potencjalny negatywny wpływ tego? Czy wszystkie aplikacje flutter powinny mieć tę linię na początku main()metody?
user482594

3
Jeśli używasz metody async w main (), musisz to dodać
Debasmita Sarkar

2
nie działa w przypadku przerwy w wersji 1.14.4 / 1.14.6 na var databasesPath = await getDatabasesPath ();
Ares91

70

Zwykle dzieje się tak, jeśli czekasz na main()metodę. Tak więc rozwiązaniem byłoby:

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

  // rest of your app code
  runApp(
    MaterialApp(...),
  );
}

1
nie działa - przerwy przy dołączaniu (await getDatabasesPath (), 'mydb.db'),
live-love

25

Nie jestem pewien, czy mam poprawną odpowiedź, ale mam ten sam błąd po ostatniej aktualizacji trzepotania i udało mi się go uruchomić, więc dzielę się swoimi odkryciami.

Wygląda na to, że błąd może być spowodowany niedawną istotną zmianą: https://groups.google.com/forum/#!msg/flutter-announce/sHAL2fBtJ1Y/mGjrKH3dEwAJ .

W rezultacie musimy ręcznie zmienić kod w następujący sposób:

  • Jeśli uruchamiasz aplikację i potrzebujesz uzyskać dostęp do binarnego komunikatora przed runApp()wywołaniem (na przykład podczas inicjalizacji wtyczki), musisz jawnie wywołać WidgetsFlutterBinding.ensureInitialized()pierwszy.
  • Jeśli uruchamiasz test, możesz wywołać TestWidgetsFlutterBinding.ensureInitialized()pierwszą linię w main()metodzie testu, aby zainicjować powiązanie.

Alternatywnie, jeśli jesteś nowicjuszem, takim jak ja, i masz trudności ze zrozumieniem powyższych i # 38464 , możesz tymczasowo uniknąć tego problemu, przełączając się na kanał beta. Po prostu uruchom "flutter channel beta". Przełomowa zmiana nie jest jeszcze w wersji beta, więc po przejściu na kanał beta nie pojawi się ten błąd przynajmniej na razie.


Dziękuję brachu, teraz właśnie użyłem wersji beta, aby uniknąć błędów!
Sopheadavid Sopheap

11

po prostu dodaj tę linię w main.dart

WidgetsFlutterBinding.ensureInitialized(); 

wygląda na to, że twój kod

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  return runApp(MultiProvider(
    providers: [
      ChangeNotifierProvider.value(
        value: AppState(),
      )
    ],
    child: MyApp(),
  ));
}

2

w moim przypadku podczas korzystania z orientacji,

przed rozwiązaniem:

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

rozwiązane użycie:

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

Chodzi o to, aby dodać WidgetsFlutterBinding.ensureInitialized () w pierwszym wierszu klasy głównej


2

Możesz napotkać to, jeśli próbujesz wykonać natywny kod wtyczki w izolacji. Dokumentacja isolate_handler tutaj dobrze to wyjaśnia:

Wtyczki używają mechanizmu zwanego kanałem platformy do komunikacji między Dart a natywnymi stronami, mechanizm przekazywania wiadomości przy użyciu typu MethodChannel. Ten mechanizm zależy od działania elementów bazowego silnika interfejsu użytkownika.

Problem polega na tym, że izolaty zapewnią wzrost wydajności tylko w przypadku kosztownego obliczeniowo kodu do rzutek. Kod platformy wtyczki ponownie użyje wątku głównego (UI).

Wywołanie WidgetsFlutterBinding.ensureInitializedwewnątrz izolacji również zakończy się niepowodzeniem z powodu braku bazowego silnika interfejsu użytkownika w izolacie.


1

Zanim miałem wersję v1.12.13+hotfix.5, przełączyłem się na wersję v1.14.4i zadziałało.

Błąd mówi, że powinieneś dodać WidgetsFlutterBinding.ensureInitialized();, ale ponieważ to nie zadziałało dla mnie, przełączyłem się na inną wersję. Jedną rzeczą, o której należy pamiętać, jest to, że nadal musisz dodać WidgetsFlutterBinding.ensureInitialized();jako pierwszą linię w swoim main!


1

Rozwiązanie: Wywołaj WidgetsFlutterBinding.ensureInitialized(); przed wywołaniem funkcji asynchronicznych.


void main() async {
  WidgetsFlutterBinding.ensureInitialized();   //  ADD THIS BEFORE YOUR ASYNC FUNCTION CALL.
  await Firestore.instance.settings(...);      //  NOW YOU CAN CALL ASYNC FUNCTION.   
  ...
  runApp(
    ...
  )

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.