Flutter: Exception non gérée: l'accès à ServicesBinding.defaultBinaryMessenger a été effectué avant l'initialisation de la liaison

134

Une solution pour résoudre ce problème?

Trace de la pile:

[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
la source
mettez cette ligne comme première instruction dans main () - WidgetsFlutterBinding.ensureInitialized ();
Vijay Ram

Réponses:

312

Ce problème est introduit lorsque vous mettez à niveau Flutter. La raison derrière cela est que vous attendez des données ou que vous exécutez une asyncfonction à l'intérieur main().

J'étais en train d'initialiser à l' ScopedModelintérieur main()et à l'intérieur que j'attendais des données.

Il y a une très petite solution. Courez à l' WidgetsFlutterBinding.ensureInitialized()intérieur void main(), avant de le faire runApp(). Fonctionne comme un charme !!

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(Delta(
    model: ProductDataModel(),
  ));
}
Debasmita Sarkar
la source
17
assurez-vous que WidgetFlutterBinding.ensureInitialized () est la première ligne de main (). puis procédez comme d'habitude
Avnish kumar
10
Quel est l'impact négatif potentiel de cela? Toutes les applications Flutter devraient-elles avoir cette ligne au début de la main()méthode?
user482594
3
Si vous utilisez la méthode async dans main (), vous devez ajouter ceci
Debasmita Sarkar
2
ne fonctionne pas pour la rupture v1.14.4 / v1.14.6 sur var databasesPath = await getDatabasesPath ();
Ares91
70

Cela se produit généralement si vous attendez une main()méthode. Donc, la solution serait:

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

  // rest of your app code
  runApp(
    MaterialApp(...),
  );
}
CopsOnRoad
la source
1
ne fonctionne pas - pause à la jointure (attendez getDatabasesPath (), 'mydb.db'),
live-love
25

Je ne sais pas si j'ai la bonne réponse, mais j'ai eu la même erreur après une récente mise à jour de flutter et j'ai réussi à la faire fonctionner, donc je partage mes résultats.

Il semble que l'erreur puisse être causée par une modification de rupture récente: https://groups.google.com/forum/#!msg/flutter-announce/sHAL2fBtJ1Y/mGjrKH3dEwAJ .

Par conséquent, nous devons modifier manuellement le code comme suit:

  • Si vous exécutez une application et que vous devez accéder à la messagerie binaire avant l' runApp()appel (par exemple, lors de l'initialisation du plugin), vous devez appeler explicitement le WidgetsFlutterBinding.ensureInitialized()premier.
  • Si vous exécutez un test, vous pouvez appeler le TestWidgetsFlutterBinding.ensureInitialized()comme première ligne dans la main()méthode de votre test pour initialiser la liaison.

Alternativement, si vous êtes un débutant comme moi et que vous avez du mal à comprendre ce qui précède et # 38464 , vous pouvez temporairement éviter ce problème en passant au canal bêta. Exécutez simplement "Flutter channel beta". Le changement de rupture n'est pas encore dans le canal bêta, donc après le passage au canal bêta, vous n'obtiendrez pas cette erreur au moins pour le moment.

Mars
la source
Merci mon frère, maintenant je viens d'utiliser la version bêta pour éviter les erreurs!
Sopheadavid Sopheap
11

ajoutez simplement cette ligne dans main.dart

WidgetsFlutterBinding.ensureInitialized(); 

votre code ressemble à

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

dans mon cas lors de l'utilisation de l'orientation,

avant résolu:

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

utilisation résolue:

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

Le but est d'ajouter WidgetsFlutterBinding.ensureInitialized () dans la première ligne de la classe principale

arjava
la source
2

Vous pourriez rencontrer cela si vous essayez d'exécuter le code natif du plugin dans un isolat. La documentation isolate_handler ici explique bien ceci:

Les plugins utilisent un mécanisme appelé canal de plate-forme pour communiquer entre le Dart et les côtés natifs, un mécanisme de transmission de messages utilisant le type MethodChannel. Ce mécanisme dépend des éléments du moteur d'interface utilisateur sous-jacent pour fonctionner.

Le problème ici est que les isolats ne fourniront une amélioration des performances que dans le cas d'un code de fléchettes coûteux en calcul. Le code de la plateforme du plugin utilisera à nouveau le thread principal (UI).

L'appel à l' WidgetsFlutterBinding.ensureInitializedintérieur d'un isolat échouera également en raison de l'absence d'un moteur d'interface utilisateur sous-jacent dans l'isolat.

sjsam
la source
1

Avant d'avoir la version v1.12.13+hotfix.5, je suis passé à la version v1.14.4et cela a fonctionné.

L'erreur dit que vous devriez ajouter WidgetsFlutterBinding.ensureInitialized();, mais comme cela n'a pas fonctionné pour moi, je suis passé à l'autre version. Une chose à garder à l'esprit cependant est que vous devez toujours ajouter WidgetsFlutterBinding.ensureInitialized();comme toute première ligne dans votre main!

hanslissi
la source
1

Solution: appelez WidgetsFlutterBinding.ensureInitialized(); avant d' appeler des fonctions asynchrones.


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