Flutter中MethodChannel/EventChannel的原理

前言

Flutter开发中或多或少都需要和原生端做一些交互,Flutter SDK中也为开发者提供了MethodChannel/EventChannel实现了Flutter调用原生端以及原生端调用Flutter。

MethodChannel

Flutter与原生端方法调用使用的是MethodChannel,它是双向通信Flutter和原生端都可以主动发起

Flutter端调用原生方法
  • Flutter端调用
const MethodChannel _channel =
    MethodChannel("com.test.methodChannel/test");
_channel.invokeMethod("getVersion", <String, dynamic>{// 如果有参数就传参数,键值对形式});
  • Android端实现
        MethodChannel methodChannel = new MethodChannel(flutterView.getAttachedFlutterEngine().getDartExecutor(),
        "com.test.methodChannel/test");

        methodChannel.setMethodCallHandler(new MethodChannel.MethodCallHandler() {
            @Override
            public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
                        switch (call.method){
                            case "getVersion":
                                result.success(1);
                                break;
                        }
            }
        });
原生调用Flutter方法
  • Flutter端实现
  MethodChannel methodChannel = MethodChannel("com.test.methodChannel/test");
  methodChannel.setMethodCallHandler((MethodCall call){
    Completer<dynamic> completer = Completer();
    switch(call.method){
      case "getFlutterInfo":
        completer.complete("Flutter Package Name is Test");
        break;
    }
    return completer.future;

  });
  • Android端调用
               MethodChannel methodChannel = new MethodChannel(flutterView.getAttachedFlutterEngine().getDartExecutor(),
        "com.test.methodChannel/test");
        methodChannel.invokeMethod("getFlutterInfo", null, new MethodChannel.Result() {
            @Override
            public void success(@Nullable Object result) {
                //拿到Flutter中getFlutterInfo方法的结果 Flutter Package Name is Tes
            }

            @Override
            public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) {

            }

            @Override
            public void notImplemented() {

            }
        });
EventChannel

EventChannel是原生端与Flutter端相互发送事件,它是单向通信的,实现原理和MethodChannel差不多

原生端发送事件到Flutter
  • Flutter端监听代码
EventChannel _eventChannel = EventChannel('com.test.eventChannel/test');
//监听原生端发送过来的事件
_eventChannel.receiveBroadcastStream().listener()
  • Android端发送代码
        EventChannel eventChannel = new EventChannel(flutterView.getAttachedFlutterEngine().getDartExecutor(),"com.test.eventChannel/test");
       EventChannel.EventSink eventSink;
        
        eventChannel.setStreamHandler(new EventChannel.StreamHandler() {
            @Override
            public void onListen(Object arguments, EventChannel.EventSink events) {
                
               eventSink = events;
            }

            @Override
            public void onCancel(Object arguments) {

            }
        });
        
//发送事件到Flutter
if(eventSink != null){
		eventSink.success(200);
}        

核心类/方法调用示意图(Flutter / Android)

image-20220118110310562

信使DartMessenger/_DefaultBinaryMessenger

无论是MethodChannel还是EventChannel它们都是面向业务上层封装好的API。查看源码可以得知Android有一个DartMessenger,而Flutter端有一个_DefaultBinaryMessenger,这两者负责接收消息和发送消息。

MethodChannel方法调用链:
  • Flutter端
  1. MethodChannel#invokeMethod
  2. _DefaultBinaryMessenger#send

PlatformDispatcher#_sendPlatformMessage

  • Android端
  1. FlutterJNI#handlePlatformMessage
  2. DartMessenger#handleMessageFromDart
  3. IncomingMethodCallHandler#onMessage
  4. MethodCallHandler#onMethodCall
  5. Reply#reply //返回值
  6. FlutterJNI#invokePlatformMessageResponseCallback
EventChannel方法调用链:
  • Android端
  1. EventChannel#setStreamHandler
  2. Flutter端注册监听
  3. EventSink#success
  4. DartMessenger#send
  5. FlutterJNI.dispatchPlatformMessage
  • Flutter端
  1. EventChannel#receiveBroadcastStream#binaryMessenger.setMessageHandler

  2. PlatformDispatcher#_dispatchPlatformMessage

  3. window.onPlatformMessage

  4. _DefaultBinaryMessenger#handlePlatformMessage

  5. 调用2.中的setMessageHandler的回调

编码器

Flutter与原生之间的交互的数据都是要经过二进制编码的,Flutter framework提供了StandardMessageCodec编码器,最终都是基于二进制传输,所以默认只支持String,int,double,bool,List,Map这几类数据的传输

总结:

通过本文分析Flutter跨端通信的流程加深对Flutter跨平台的认识,从语言层面它是Java --> C/C++ —> Dart 的一个调用。从整体架构上来看分为消息处理器、编码器、信使、消息传输等结构,类比JsBridge等框架结构类似。

FlutterMethodChannel是一种在Flutter和原生平台(如iOS)之间进行通信的机制。它允许Flutter应用程序调用原生平台上的方法,并且还可以让原生平台调用Flutter的方法。 在iOS上使用MethodChannel,首先需要在原生平台(Objective-C或Swift)的代码创建一个MethodChannel实例。这个实例需要一个唯一的通道名称,以便Flutter可以识别它。然后,可以使用该MethodChannel实例来注册方法,并指定一个方法名称和一个回调函数来处理该方法被调用时的逻辑。 在Flutter应用程序,可以使用MethodChannel的实例来调用原生平台上注册的方法。可以指定方法名称和传递参数(如果需要)。MethodChannel会将这个方法调用发送到原生平台,并等待原生平台返回结果。一旦结果返回,可以在Flutter端处理它。 使用MethodChannel时需要注意一些事项。首先,MethodChannel只能传递符合平台限制的数据类型,如字符串、数字、布尔值等。如果需要传递复杂的数据结构,可以将数据转换为平台能够识别的格式(如JSON),然后再进行传递。其次,MethodChannel是一种异步通信机制,所以在处理方法调用时需要考虑异步操作和结果处理的情况。 总的来说,FlutterMethodChannel是一种强大而灵活的机制,可以实现Flutter应用程序与原生平台之间的双向通信。它为开发人员提供了在FlutteriOS之间传递方法调用和数据的能力,可以实现更高级的功能和交互体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值