The flutter plugins are not loading when used with FlutterFragment
. However, they are working fine when used with FlutterActivity
.
Ends up with the following exception for exception
E [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: PlatformException(channel-error, Unable to establish connection on channel., null, null) #0 InstanceManagerHostApi.clear (package:camera_android_camerax/src/camerax_library.g.dart:315:7)
I have 2 plugins and all are failing with the same exception.
flutter_native_barcode_scanner
fl_location
Usually problem like this happens when plugins are not registered. From this moment, I will treat your problem, as if you followed the official add-to-app guide for Android, meaning:
FragmentActivity
or AppCompatActivity
or something similar, not related to Flutter
.FlutterFragment
and create it with FlutterFragment.createDefault
.This 2 points are crucial for understand, but even if your setup is a bit different, I will provide some universal advices.
So, main issue here is that default flutter engine created with FlutterFragment is not automatically register plugins. proof
There are several ways to change that. Here is some of them:
Use FlutterFragmentActivity
as host activity for your fragment. Unfortunately, will not work because of this issue
(I prefer this) Register plugins yourself by overriding FlutterFragment
. Take a look at example:
First, create your own fragment (you can use any name):
import io.flutter.embedding.android.FlutterFragment
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
class MyFlutterFragment : FlutterFragment() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
GeneratedPluginRegistrant.registerWith(flutterEngine)
}
}
It is actually boilerplate code, sou you can just copy-paste it if you do not need another overrides.
Then, you should create instance of your own Fragment
, but with tools provided from Flutter. It's tricky part, at least for me:
// This is how Flutter documentation advices to create fragment:
if (flutterFragment == null) {
// Main line is here
var newFlutterFragment = FlutterFragment.createDefault()
//
flutterFragment = newFlutterFragment
fragmentManager
.beginTransaction()
.add(
R.id.fragment_container,
newFlutterFragment,
TAG_FLUTTER_FRAGMENT
)
.commit()
}
}
// Instead, you will create your MyFlutterPlugin like this:
var newFlutterFragment = FlutterFragment.NewEngineFragmentBuilder(MyFlutterFragment::class.java).build<MyFlutterFragment>()
// Full example:
val fragmentManager: FragmentManager = supportFragmentManager
flutterFragment = fragmentManager
.findFragmentByTag(TAG_FLUTTER_FRAGMENT) as FlutterFragment?
if (flutterFragment == null) {
var newFlutterFragment = FlutterFragment.NewEngineFragmentBuilder(MyFlutterFragment::class.java)
.build<MyFlutterFragment>()
flutterFragment = newFlutterFragment
fragmentManager
.beginTransaction()
.add(
binding.navHostFragmentContentMain.id,
newFlutterFragment,
TAG_FLUTTER_FRAGMENT
)
.commit()
}
This was an corrected example from official docs
TLDR;
So, main point here is that it is obligatory to register plugins manually when working with FlutterFragments
I created a GitHub repo with reproduction of your problem and described solution: https://github.com/Sameri11/flutter-add-to-app-example.
On main
branch app works, on plugins_crash
there are same errors in log as yours.
You are free to use this code.