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

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时,从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方法。

从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层回复。
任重而道远
网友评论