美文网首页
Flutter通信流程

Flutter通信流程

作者: gczxbb | 来源:发表于2019-12-09 18:38 被阅读0次

    一、整体结构

    (Android)负责Flutter原生和Dart层通信的类。
    FlutterView,视图层,SurfaceView子类。
    FlutterNativeView,将视图层JIN部分抽离,和FlutterJNI相关的类。
    DartExecutor,DartMessenger包装者类。
    DartMessenger,二进制消息信使,通过FlutterJNI和底层(C++)通信,实现两个接口,同时具有发送和接收Dart消息功能。
    FlutterJNI,JNI相关类,native方法。
    BinaryMessenger,接口,向Dart层发送消息。
    PlatformMessageHandler,接口,接收Dart层消息。
    MethodChannel,通道,代表一个调用通道,即数据流管道。

    BinaryMessenger继承关系

    FlutterView,FlutterNativeView,DartExecutor和DartMessenger四个类全部实现接口(消息发送)BinaryMessenger,全部方法@UiThread注解,在主线程工作。
    DartMessenger类实现接口(消息接收)PlatformMessageHandler。

    通信模型

    二、Channel注册

    1,MethodChannel

    在Android原生组件启动时进行通道注册,所谓Channel,其实就是原生和Dart数据流通的一条管道。它提供invokeMethod方法,触发Send Message到Dart,向信使注册Handler,处理Dart层消息。

    public MethodChannel(BinaryMessenger messenger, String name) {
        this(messenger, name, StandardMethodCodec.INSTANCE);
    }
    

    定义一个MethodChannel对象,通道名代表它的唯一性,我的理解就是一组相似的原生功能方法可以放在一个通道中。至于原生提供的内容,Flutter并没有集成,需要自己实现。Flutter只提供数据流通道。原生功能例如权限,和Android Sdk平台相关大。
    通道名和信使BinaryMessenger,信使即视图层FluttetView,从FlutterActivity中可以获取到。

    2,实现MethodCallHandler接口

    自定义原生处理类。

    @Override
    public void onMethodCall(MethodCall call, MethodChannel.Result result) {
        //根据不同MethodCall,实现
    }
    

    onMethodCall方法,实现具体功能。

    @UiThread
    public void setMethodCallHandler(@Nullable MethodChannel.MethodCallHandler handler) {
        this.messenger.setMessageHandler(this.name, handler == null ? null : new MethodChannel.IncomingMethodCallHandler(handler));
    }
    

    将自定义类进行一步BinaryMessageHandler类封装,原因是将Dart传输的Byte数组解析成MethodCall(onMethodCall方法第一个参数)。
    注册时,每个通道都会创建一个BinaryMessageHandler,即IncomingResultHandler。

    注册后,将通道名和BinaryMessageHandler处理器保存在DartMessager的Map中。

    IncomingResultHandler,实现BinaryMessageHandler接收,原生调Dart,等Dart回复,统一Dart消息处理器,接收到Dart层传输的是byteBuffer字节数组。
    MethodChannel.Result,Dart调原生的回复结果,(onMethodCall方法第二个参数)。当onMethodCall方法结束,将结果转换byteBuffer,转发给BinaryReply。
    DartMessage.Reply,信使内部类,实现BinaryReply,Dart调用原生的公用回复类,通过FlutterJNI回复Dart,通道层结果MethodChannel.Result类会将结果转换byteBuffer。


    三、原生调Dart

    1,示例

    原生层,定义一个MethodChannel,调用Channel的invokeMethod方法,第一个参数定义的Dart层的方法,第二个是传递实参。

    //访问Dart
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            channel.invokeMethod("getDartString", "我要去dart层了!");
        }
    }, 1000);
    

    Dart层,定义一个MethodChannel,设置setMethodCallHandler接收器,等待原生调用。根据方法名,执行不同逻辑。

    static const _platform_string = const MethodChannel(
        "xxxxx"); //获取Dart层string
    
     _platform_string.setMethodCallHandler((handler) {
      switch (handler.method) {
        case "getDartString":
          var argument = handler.arguments;
          print("arguments:$argument");
          break;
      }
    });
    
    2,流程(原生层)
    原生调Dart 数据流

    原生调用Dart时,从MethodChannel的invokeMethod方法发起。

    @UiThread
    public void invokeMethod(String method, @Nullable Object arguments, MethodChannel.Result callback) {
        this.messenger.send(this.name, 
            this.codec.encodeMethodCall(new MethodCall(method, arguments)), 
            callback == null ? null : new MethodChannel.IncomingResultHandler(callback));
    }
    

    将method和arguments解析成byteBuffer,回调MethodChannel.Result封装在一个通用回复对象IncomingResultHandler中,负责字节流转换。
    通过BinaryMessenger的send方法发送,在DartMessager类保存一个等待回复的Map表,BinaryReply类型。
    当handlePlatformMessageResponse方法被触发时,代表Dart层回复,根据发送replyId在Map表中查找BinaryReplay,将回复字节数组转换成对象,交给MethodChannel.Result。

    消息经过FlutterView、FlutterNativeView的send方法,到DartExecutor,DartMessenger对象,最后,在FlutterJNI进入native(C++)层。


    四、Dart调原生

    Dart端
    从Dart端进入,dart:BinaryMessenger的send方法,调用ui.window.sendPlatformMessage方法,
    _sendPlatformMessage方法,进入native,Window_sendPlatformMessage方法。

    Dart调原生流程

    从native(C++)进入原生层接收端,两种情况。
    1,Dart主动调用,handleMessageFromDart方法,
    2,Dart回复,handlePlatformMessageResponse方法。
    在原生调Dart时,Dart回复。当Dart层主动调用时,从handleMessageFromDart方法开始,根据channel通道名查找注册的BinaryMessageHandler。
    通过setMethodCallHandler方法注册的通道处理类,进入IncomingResultHandler的onMessage方法,将byteBuffer转换成MethodCall。

    实现自己的onMethodCall方法,然后通知Dart调用结果,返回结果类型不同,在MethodChanneld.Result层统一类型转换成byteBuffer,转发给公用回复类,最后通过FlutterJNI,将byteBuffer发送给native(C++),向Dart层回复。


    任重而道远

    相关文章

      网友评论

          本文标题:Flutter通信流程

          本文链接:https://www.haomeiwen.com/subject/tqqkgctx.html