DART代码无法在Flutter插件中找到平台实现

发布于 2025-02-14 00:54:34 字数 269 浏览 3 评论 0原文

我创建了Flutter插件。但是我还需要添加更多渠道。因此,我同时创建了DART代码和本机实现。问题在于,飞镖代码无法找到本机实现,因此它散发出消息“未手持例外:缺少pluginexception(未找到方法...)”,

我将我的本机实现与样品板实现进行了比较,我不喜欢t看到任何错误。我有正确的频道名称。我已经注册了频道。我的频道名称当然与Builderplate实现的频道名称不同。但它与飞镖代码中的一个相匹配。

我想知道,即使我代表不同的功能块,我是否需要所有本机实现都具有相同的频道名称?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

初与友歌 2025-02-21 00:54:34

您可以为插件创建多个方法渠道,并为每个方法频道分配一个单独的MethodCallHandler。这样,如果在不同的频道中,您可以处理两种具有相同名称的方法。

这是我如何更改“颤动插件”模板以支持多个方法通道的方式。

PS:我使用了Flutter 2.10.5插件模板,因为它更容易理解。在Flutter 3中,他们在飞镖侧添加了一个接口。

飞镖:

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!")
  }
}

完成源代码: https://github.com/colinschmale/example_plugin

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文