Reputation: 413
I created Flutter plugin. But I also need to add more channels. So I created both dart code and the native implementation. The problem is that the dart code cannot find the native implementation, so it throw out error with the message "Unhandled exception: MissingPluginException (No implementation found for method ...)"
I compared my native implementation with the boilerplate implementation, I don't see anything wrong. I have the correct channel name. I have registered the channel. My channel name is certainly different from the builderplate implementation's channel name. But it matches the one in dart code.
I wonder if I need to have all my native implementations to have the same channel name even though they represent different functionality blocks?
Upvotes: 0
Views: 1222
Reputation: 360
You can create multiple MethodChannels for your plugin and assign an individual MethodCallHandler to each MethodChannel. That way you can handle two methods with the same name differently if they are in different channels.
Here is how I've changed the Flutter plugin template to support multiple MethodChannels.
P.S.: I've used the Flutter 2.10.5 plugin template because it's a bit easier to understand. In Flutter 3 they've added an interface on the Dart side.
Dart:
class ExamplePlugin {
static const MethodChannel _channel = MethodChannel('example_plugin');
static const MethodChannel _channel2 = MethodChannel('example_plugin2');
static Future<String?> get platformVersion async {
final String? version = await _channel.invokeMethod('getPlatformVersion');
return version;
}
static Future<String?> get helloWorld async {
final String? helloWorld = await _channel2.invokeMethod('getHelloWorld');
return helloWorld;
}
}
Kotlin:
class ExamplePlugin: FlutterPlugin {
private lateinit var channel : MethodChannel
private lateinit var channel2 : MethodChannel
private val firstMethodCallHandler = FirstMethodCallHandler()
private val secondMethodCallHandler = SecondMethodCallHandler()
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
channel = MethodChannel(flutterPluginBinding.binaryMessenger, "example_plugin")
channel.setMethodCallHandler(firstMethodCallHandler)
channel2 = MethodChannel(flutterPluginBinding.binaryMessenger, "example_plugin2")
channel2.setMethodCallHandler(secondMethodCallHandler)
}
override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
channel.setMethodCallHandler(null)
channel2.setMethodCallHandler(null)
}
private inner class FirstMethodCallHandler: MethodCallHandler {
override fun onMethodCall(call: MethodCall, result: Result) {
if (call.method == "getPlatformVersion") {
result.success("Android ${android.os.Build.VERSION.RELEASE}")
} else {
result.notImplemented()
}
}
}
private inner class SecondMethodCallHandler: MethodCallHandler {
override fun onMethodCall(call: MethodCall, result: Result) {
if (call.method == "getHelloWorld") {
result.success("Hello World!")
} else {
result.notImplemented()
}
}
}
}
Swift:
public class SwiftExamplePlugin: NSObject, FlutterPlugin {
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "example_plugin", binaryMessenger: registrar.messenger())
let channel2 = FlutterMethodChannel(name: "example_plugin2", binaryMessenger: registrar.messenger())
channel.setMethodCallHandler(firstMethodCallHandler)
channel2.setMethodCallHandler(secondMethodCallHandler)
}
static public func firstMethodCallHandler(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
result("iOS " + UIDevice.current.systemVersion)
}
static public func secondMethodCallHandler(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
result("Hello World!")
}
}
Complete source code: https://github.com/ColinSchmale/example_plugin
Upvotes: 1