请选择 进入手机版 | 继续访问电脑版

默认
发表评论 0
想开发IM:买成品怕坑?租第3方怕贵?找开源自已撸?尽量别走弯路了... 找站长给点建议
Flutter Platform Channel深度解析
一、简介
Platform Channel 是 Flutter 端与 Platform 端制定的通信机制,由官方提供用于 Dart 和平台之间的相互通信。
分为以下 3 种
(1)BaseMessageChannel :用于传递字符串和半结构化的信息(在大内存数据块传递的情况下使用)
(2)MethodChannel:用于传递方法调用(Method Invocation)
(3)EventChannel: 用于数据流(Event Streams)的通信

二、消息传递与编码器

Flutter 的消息传递工具是 BinaryMessager ,通过它与 Platform 建立起通信关系,消息以二进制的格式进行传递。


如图所示 BinaryMessager 的传递需要经过 BinaryMessageHandler,BinaryMessagerHandler 是以 Channel Name 作为键值生成出来再被注册到 BinaryMessager 上的,BinaryMessageHandler 和 BinaryMessager 是一一对应的,二进制格式的消息通过消息编码器(Codec)解码为可识别的信息,并传递给 Handler 进行处理。Handler 处理完后,会把结果编码为二进制格式,再通过回调函数返回结果并发送回 Flutter 端。

1.编码器分类

(1)MessageCodec:BinaryCodec、StringCodec、JSONMessageCodec、StandardMessageCodec
(2)MethodCodec:JSONMethodCodec、StandardMessageCodec


经过消息编码器处理后,消息就可以被 Handler 进行处理了。

2.消息编码过程

Android 端的返回值是 java.lang.Integer 类型的,而 iOS 端返回值则是一个 NSNumber 类型的(通过 NSNumber numberWithInt:获取)。而到了 Flutter 端时,这个返回值自动“变成 ”了 Dart 语言的 Int 类型。
standard platform channels 使用 standard messsage codec 对 message 和 response 进行序列化和反序列化,message与 response 可以是 booleans, numbers, Strings, byte buffers,List, Maps 等等,而序列化后得到的则是二进制格式的数据。

Flutter 默认的消息编码器是 StandardMessageCodec ,支持的数据类型如下:


三、MethodChannel

MethodChannel 是 Flutter 与 Platform 之间传递信息的一种,其传递过程是:BinaryMessager > BinaryMessagerHandler > MethodChannel。


如上图:Native 端(iOS 和 Android)为宿主端(host),Flutter 则是客户端(client),Flutter 调用 Native 方法时,需要传递的信息是通过平台通道传递到宿主端的,Native 收到调用的信息后方可执行指定的操作。如有返回的数据,则 Native 会将数据再通过平台通道一并传递给 Flutter,其中数据传递是异步的,这样就能确保消息传递时用户界面不会被阻塞。

1.Flutter 层(Dart 层)

Flutter 端使用 MethodChannel 的 invokeMethod 方法发起一次方法调用时,开始了消息传递流程。invokeMethod 方法会将其入参 message 和 arguments 封装成一个 MethodCall 对象,并使用 MethodCodec 将其编码为二进制格式数据,再通过 BinaryMessages 将消息发出。(注意,此处提到的类名与方法名均为 Dart 层的实现)

上述过程最终会调用到 ui.Window 的 _sendPlatformMessage 方法,该方法是一个Native 方法,其实现在 Native 层,这与 Java 的 JNI 技术非常类似。我们向 Native 层发送了三个参数:
• name,String 类型,代表 Channel 名称
• data,ByteData 类型,即之前封装的二进制数据
• callback,Function 类型,用于结果回调

2.Native 层

到 Native 层后,window.cc 的 SendPlatformMessage 方法接受了来自 Dart 层的三个参数,并对它们做了一定的处理:Dart 层的回调 callback 封装为 Native 层的 PlatformMessageResponseDart 类型的 response;dart 层的二进制数据 data 转化为 std::vector<uint8t> 类型数据 data;根据 response, data 以及 Channel 名称 name 创建一个 PlatformMessage 对象,并通过dartstate->window()->client()->HandlePlatformMessage 方法处理 PlatformMessage 对象。

dart_state->window()->client()是一个 WindowClient,而其具体的实现为 RuntimeController,RuntimeController 会将消息交给其代理 RuntimeDelegate 处理。

RuntimeDelegate 的实现为 Engine,Engine 在处理 Message 时,会判断该消息是否是为了获取资源(channel 等于"flutter/assets"),如果是,则走获取资源逻辑,否则调用 Engine:elegate 的 OnEngineHandlePlatformMessage 方法。

Engine:elegate 的具体实现为 Shell,其 OnEngineHandlePlatformMessage 接收到消息后,会向 PlatformTaskRunner 添加一个 Task,该 Task 会调用 PlatformView 的 HandlePlatformMessage 方法。值得注意的是,Task 中的代码执行在 Platform Task Runner 中,而之前的代码均执行在 UI Task Runner 中。

四、消息处理

PlatformView 的 HandlePlatformMessage 方法在不同平台有不同的实现,但是其基本原理是相同的。


1.PlatformView

AndroidPlatformViewAndroid 是 Platformview 的子类,也是其在 Android 端的具体实现。当 PlatformViewAndroid 接收到 PlatformMessage 类型的消息时,如果消息中有 response(类型为 PlatformMessageResponseDart),则生成一个自增长的 responseid,并以 responseid 为key,response 为 value 存入字典 pendingresponses 中。接着,将 channel 和 data 均转化为 Java 可识别的数据,通过 JNI 向 Java 层发起调用,将 response_id、channel 和 data 传递过去。

Java 层中,被调用的代码为 FlutterNativeView (BinaryMessager 的具体实现)的 handlePlatformMessage ,该方法会根据 channel 找到对应的 BinaryMessageHandler 并将消息传递给它处理。

BinaryMessageHandler 处理完成后,FlutterNativeView 会通过 JNI 调用 native 的方法,将 responsedata 和 responseid 传递到 native 层。

Native 层,PlatformViewAndroid 的 InvokePlatformMessageResponseCallback 接收到了 respondid 和 responsedata。其先将 responsedata 转化为二进制结果,并根据 responseid,从 pandingresponses 中找到对应的 PlatformMessageResponseDart 对象,调用其 Complete 方法将二进制结果返回。

2.PlatformViewIOS

PlatformViewIOS 是 PlatformView 的子类,也是其在 iOS 端的具体实现,当 PlatformViewIOS 接收到 message 时会交给 PlatformMessageRouter 处理。

PlatformMessageRouter通过 PlatformMessage 中的 channel 找到对应的 FlutterBinaryMessageHandler,并将二进制消息其处理,消息处理完成后,直接调用 PlatformMessage 对象中的 PlatformMessageResponseDart 对象的 Complete 方法将二进制结果返回。

3.结果回传

PlatformMessageResponseDart 的 Complete 方法向 UI Task Runner 添加了一个新的 Task,这个 Task 的作用是将二进制结果从 native 的二进制数据类型转化为 Dart 的二进制数据类型 response,并调用 Dart 的 callback 将 response 传递到 Dart 层。

Dart 层接收到二进制数据后,使用 MethodCodec 将数据解码,并返回给业务层。至此,一次从 Flutter 发起的方法调用就完整结束了。

五、具体使用


1.Flutter 端调用 Android 方法

2.Android 端代码

(1)继承 MethodCallHandler 并设置 Handler ,MethodChannel 需要保存在对象一会调用回调时需要使用,onMethodCall 为 Flutter 层回调的方法这边用 RCIMFlutterWrapper 承接处理。


(2)RCIMFlutterWrapper 类中处理, MethodCall 的 Method,对应 Flutter 层调用 invokeMethod 方法的传入的第一个参数,两端需完全对应一致。


(3)直接通过 result 对象回调回去,这样就能将结果回调。

3.关于 Android 回调 Flutter 的使用


(1)Flutter 端回调监听,设置监听 Key 两端对应。


(2)Android 端代码回调,mChannel.invokeMethod 方法将数据回调给 Flutter 层。

即时通讯网 - 即时通讯开发者社区! 来源: - 即时通讯开发者社区!

推荐方案
打赏楼主 ×
使用微信打赏! 使用支付宝打赏!

返回顶部