Search code examples
flutterbindingcameraandroid-camera

Flutter : `camera_android` threw an error: Binding has not yet been initialized


Regression. After upgrading plugins my app does not start anymore.

this my flutter spec:

Flutter is already up to date on channel stable

Flutter 3.0.2 • channel stable • https://github.com/flutter/flutter.git

Framework • revision cd41fdd (10 days ago) • 2022-06-08 09:52:13 -0700

Engine • revision f15f824b57 Tools • Dart 2.17.3 • DevTools 2.12.2

Previously everythings was working fine but I am getting this error :

I/flutter ( 6677): `camera_android` threw an error: Binding has not yet been initialized.
I/flutter ( 6677): The "instance" getter on the ServicesBinding binding mixin is only available once that binding has been initialized.
I/flutter ( 6677): Typically, this is done by calling "WidgetsFlutterBinding.ensureInitialized()" or "runApp()" (the latter calls the former). Typically this call is done in the "void main()" method. The "ensureInitialized" method is idempotent; calling it multiple times is not harmful. After calling that method, the "instance" getter will return the binding.
I/flutter ( 6677): In a test, one can call "TestWidgetsFlutterBinding.ensureInitialized()" as the first line in the test's "main()" method to initialize the binding.
I/flutter ( 6677): If ServicesBinding is a custom binding mixin, there must also be a custom binding class, like WidgetsFlutterBinding, but that mixes in the selected binding, and that is the class that must be constructed before using the "instance" getter.. The app may not function as expected until you remove this plugin from pubspec.yaml
E/flutter ( 6677): [ERROR:flutter/shell/common/shell.cc(93)] Dart Unhandled Exception: Binding has not yet been initialized.
E/flutter ( 6677): The "instance" getter on the ServicesBinding binding mixin is only available once that binding has been initialized.
E/flutter ( 6677): Typically, this is done by calling "WidgetsFlutterBinding.ensureInitialized()" or "runApp()" (the latter calls the former). Typically this call is done in the "void main()" method. The "ensureInitialized" method is idempotent; calling it multiple times is not harmful. After calling that method, the "instance" getter will return the binding.
E/flutter ( 6677): In a test, one can call "TestWidgetsFlutterBinding.ensureInitialized()" as the first line in the test's "main()" method to initialize the binding.
E/flutter ( 6677): If ServicesBinding is a custom binding mixin, there must also be a custom binding class, like WidgetsFlutterBinding, but that mixes in the selected binding, and that is the class that must be constructed before using the "instance" getter., stack trace: #0      BindingBase.checkInstance.<anonymous closure> (package:flutter/src/foundation/binding.dart:281:9)
E/flutter ( 6677): #1      BindingBase.checkInstance (package:flutter/src/foundation/binding.dart:363:6)
E/flutter ( 6677): #2      ServicesBinding.instance (package:flutter/src/services/binding.dart:48:54)
E/flutter ( 6677): #3      MethodChannel.setMethodCallHandler (package:flutter/src/services/platform_channel.dart:387:51)
E/flutter ( 6677): #4      new AndroidCamera (package:camera_android/src/android_camera.dart:26:13)
E/flutter ( 6677): #5      AndroidCamera.registerWith (package:camera_android/src/android_camera.dart:32:31)
E/flutter ( 6677): #6      _PluginRegistrant.register (file:///Users/manish/Documents/REBORN/flutter/user-app/.dart_tool/flutter_build/dart_plugin_registrant.dart:47:23)
E/flutter ( 6677): 

Solution

  • Yeah, they released 0.9.8+1 as a broken build.

    https://github.com/flutter/flutter/issues/106236#issuecomment-1161100481

    This is an unintended side effect of moving to a per-package platform channel. The default method channel didn't have this problem because static class fields are lazily evaluated in Dart, so the default method channel class constructor was only being run once the camera is actually used, whereas the new version's constructors are explicitly triggered in registerWith(). We'll need to make the reverse channel creation lazy in those implementations, rather than setting it up in the constructor.

    Recommended

    Until they fix the build, I recommend:

    https://github.com/flutter/flutter/issues/106236#issuecomment-1161149799

    1. Delete pubspec.lock
    2. Downgrade to 0.9.7+1 (versions 0.9.8 and 0.9.8+1 throw the error)
      https://pub.dev/packages/camera/versions
    3. Run flutter pub get

    Not recommend at all

    Another solution would be to override dependencies

    https://github.com/flutter/flutter/issues/106236#issuecomment-1159447210

    dependency_overrides:
      camera_android: 0.9.7+1
      camera_avfoundation: 0.9.7+1
    

    I don't recommend this approach, because (a) the build is broken, and this is a hack that might not fix all issues, (b) these are additional lines of code that slow down your build and get added to your repository history, and (c) you'll need to remember to remove these lines of code.

    The Flutter team also does not recommend this approach. They refer to the override code as an "anti-pattern[s]"...
    https://github.com/flutter/flutter/issues/106236#issuecomment-1162916231 https://github.com/flutter/flutter/issues/106236#issuecomment-1162941742