กระพือ: ข้อยกเว้นที่ไม่สามารถจัดการได้: ServicesBinding.defaultBinaryMessenger ถูกเข้าถึงก่อนที่การเชื่อมโยงจะเริ่มต้น


135

วิธีแก้ปัญหานี้หรือไม่?

stacktrace:

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

วางบรรทัดนี้เป็นคำสั่งแรกของคุณใน main () - WidgetsFlutterBinding.ensureInitialized ();
Vijay Ram

คำตอบ:


316

ปัญหานี้เกิดขึ้นเมื่อคุณอัปเกรด Flutter เหตุผลที่อยู่เบื้องหลังนี้คือคุณกำลังรอข้อมูลบางส่วนหรือการทำงานภายในฟังก์ชันasyncmain()

ฉันกำลังเริ่มต้นจากScopedModelภายในmain()และภายในซึ่งฉันกำลังรอข้อมูลบางอย่าง

มีการแก้ไขเล็กน้อยมาก ทำงานเพียงแค่WidgetsFlutterBinding.ensureInitialized()ภายในก่อนที่คุณจะทำอย่างไรvoid main() runApp()ใช้งานได้อย่างมีเสน่ห์ !!

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

17
ตรวจสอบให้แน่ใจว่า WidgetFlutterBinding.ensureInitialized () เป็นบรรทัดแรกของ main () แล้วดำเนินการตามปกติ
Avnish kumar

10
อะไรคือผลกระทบเชิงลบที่อาจเกิดขึ้นจากสิ่งนี้? แอพพลิเคชั่น Flutter ทั้งหมดควรมีบรรทัดนั้นอยู่ที่จุดเริ่มต้นของmain()วิธีการหรือไม่?
user482594

3
หากคุณใช้วิธี async ใน main () คุณต้องเพิ่มสิ่งนี้
Debasmita Sarkar

2
ไม่ทำงานสำหรับ v1.14.4 / v1.14.6 แตกบน var databasesPath = รอ 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(...),
  );
}

1
ไม่ทำงาน - หยุดพักเมื่อเข้าร่วม (รอ getDatabasesPath (), 'mydb.db'),
live-love

25

ไม่แน่ใจว่าฉันมีคำตอบที่ถูกต้องหรือไม่ แต่ฉันได้รับข้อผิดพลาดเดียวกันหลังจากการอัปเกรดที่กระพือเมื่อเร็ว ๆ นี้และได้รับการจัดการเพื่อให้ใช้งานได้ดังนั้นฉันจึงแบ่งปันสิ่งที่พบ

ดูเหมือนว่าข้อผิดพลาดที่อาจจะเกิดจากการเปลี่ยนแปลงทำลายล่าสุด: https://groups.google.com/forum/#!msg/flutter-announce/sHAL2fBtJ1Y/mGjrKH3dEwAJ

ด้วยเหตุนี้เราจึงต้องเปลี่ยนรหัสด้วยตนเองดังนี้:

  • หากคุณกำลังเรียกใช้แอปพลิเคชันและต้องการเข้าถึงไบนารีแมสเซนเจอร์ก่อนที่จะrunApp()ถูกเรียก (ตัวอย่างเช่นในระหว่างการเริ่มต้นปลั๊กอิน) คุณจะต้องเรียกสิ่งWidgetsFlutterBinding.ensureInitialized()แรกอย่างชัดเจน
  • หากคุณกำลังทำการทดสอบคุณสามารถเรียกTestWidgetsFlutterBinding.ensureInitialized()เป็นบรรทัดแรกในmain()วิธีการทดสอบของคุณเพื่อเริ่มต้นการเชื่อมโยง

หรืออีกวิธีหนึ่งหากคุณเป็นมือใหม่เช่นเดียวกับฉันและมีปัญหาในการทำความเข้าใจข้างต้นและ# 38464คุณสามารถหลีกเลี่ยงปัญหานี้ได้ชั่วคราวโดยเปลี่ยนไปใช้เวอร์ชันเบต้า เพียงเรียกใช้ "flutter channel beta" การเปลี่ยนแปลงขั้นสุดท้ายยังไม่อยู่ในเวอร์ชันเบต้าดังนั้นหลังจากเปลี่ยนไปใช้เวอร์ชันเบต้าแล้วคุณจะไม่ได้รับข้อผิดพลาดนี้อย่างน้อยในตอนนี้


ขอบคุณครับตอนนี้ฉันเพิ่งใช้เวอร์ชันเบต้าเพื่อหลีกเลี่ยงข้อผิดพลาด!
Sopheadavid Sopheap

12

เพียงเพิ่มบรรทัดนี้ใน 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 ที่นี่อธิบายสิ่งนี้ได้ดี:

ปลั๊กอินใช้กลไกที่เรียกว่า platform channel เพื่อสื่อสารระหว่าง Dart และฝั่งเนทีฟซึ่งเป็นกลไกการส่งผ่านข้อความโดยใช้ประเภท MethodChannel กลไกนี้ขึ้นอยู่กับองค์ประกอบของกลไก UI ที่ทำงานอยู่

สิ่งที่จับได้คือไอโซเลตจะช่วยเพิ่มประสิทธิภาพในกรณีของรหัสโผที่มีราคาแพงในการคำนวณเท่านั้น โค้ดแพลตฟอร์มของปลั๊กอินจะใช้เธรดหลัก (UI) อีกครั้ง

การโทรWidgetsFlutterBinding.ensureInitializedภายในไอโซเลทก็จะล้มเหลวเช่นกันเนื่องจากไม่มีเอ็นจิ้น UI พื้นฐานในไอโซเลท


1

ก่อนที่ฉันจะมีเวอร์ชันv1.12.13+hotfix.5จากนั้นฉันก็เปลี่ยนไปใช้เวอร์ชันv1.14.4และใช้งานได้

ข้อผิดพลาดบอกว่าคุณควรเพิ่มWidgetsFlutterBinding.ensureInitialized();แต่เนื่องจากไม่ได้ผลสำหรับฉันฉันจึงเปลี่ยนไปใช้เวอร์ชันอื่น สิ่งหนึ่งที่ควรทราบก็คือคุณยังต้องเพิ่มWidgetsFlutterBinding.ensureInitialized();เป็นบรรทัดแรกในหลักของคุณ!


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(
    ...
  )

0

คำตอบที่โพสต์ในปัญหา GitHub 47033 ช่วยแก้ปัญหาของฉันได้

ปัญหา: https://github.com/flutter/flutter/issues/47033

วิธีแก้ปัญหาที่เหมาะกับฉัน: https://github.com/flutter/flutter/issues/47033#issuecomment-571936089

ฉันคิดว่านี่เป็นปัญหาเกี่ยวกับโปรแกรมแก้ไขด่วน flutter เวอร์ชัน 1.12.13 + การดาวน์เกรด Flutter อาจช่วยได้เช่นกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.