Flutter 与原生交互
一.信息传递方面
1.通过dart的Channel进行通信
平台通道的作用是在 Flutter 和设备之间传递消息,如下所示:
Flutter 中平台特定的 API 支持并不依赖于代码生成,而是依赖于灵活的消息传递方式:
应用程序的 Flutter 部分通过平台通道(Platform Channel)将消息发送到该应用程序的设备平台(Android 或 iOS)
设备平台通过对平台通道的监听接收到消息之后,调用设备平台上对应的 API(使用设备平台原生开发语言),然后将响应数据发送回应用程序的 Flutter 部分
1).平台通道类型
Flutter 中定义了三种不同类型的平台通道
-
BasicMessageChannel:用于传递字符串和半结构化的消息
-
MethodChannel 和 OptionalMethodChannel:用于传递方法调用
-
EventChannel:用于传递数据流
上述三种类型的平台通道相互独立,都有着各自的用途。从源码的角度来说,每个平台通道都有三个非常重要的成员变量:
name: String 类型,表示平台通道的名称,也是通道的唯一标识符
BinaryMessenger: BinaryMessenger 类型,用于表示消息,是接收和发送消息的具体实现
codec: MessageCodec 或者 MethodCodec 类型,是消息的编解码器
name
name 属性是平台通道的唯一标识符。一个 Flutter 应用中可能会存在多个平台通道,每一个平台通道在创建时必须指定一个位移的 name 属性(Flutter 使用该属性来区分每一个通道)。
当有消息从 Flutter 端发送到设备平台时,会根据其传递过来的 name 属性找到该通道对应的 Handler(消息处理器)。
BinaryMessenger
上述三种类型的平台通道都是通过 BinaryMessenger 达到与 Flutter 通信的目的的:
BinaryMessenger 使用的消息数据格式为二进制格式的数据。当我们初始化一个通道并向该通道注册消息处理器(Handler)时,实际上会生成一个与之对应的 BinaryMessageHandler,并以通道的唯一标示符(name)作为 key 存储到 Map<String, _MessageHandler> _handlers (定义在 platform_messages.dart/BinaryMessages 中)对象中。当我们需要使用 BinaryMessenger 发送消息时,会根据 name 属性查找对应的 BinaryMessageHandler,然后完成消息的发送。
BinaryMessages 在 Android 端是一个接口,其具体实现是 FlutterNativeView。在 iOS 端是一个协议,其名称为 FlutterBinaryMessenger,FlutterViewController 遵循了它。
由于平台通道从 BinaryMessengerHandler 接收到的消息是二进制格式的,需要使用 codec 将消息解码为可识别的数据并传递给 Handler 进行处理。
当 Handler 处理完消息之后,会通过回调方法返回 result,并将 result 通过 codec 编码为二进制数据,最终通过 BinaryMessenger 发送回 Flutter。
2).MethodChannel,EventChannel,BasicMessageChannel通信示例
MethodChannel 通信示例:
flutter端调用平台端系统电量方法
iOS端调用系统电量实现
Android端调用系统电量实现
EventChannel通信示例:
flutter端接收平台端系统电量方法
iOS端调用系统电量实现
Android端调用系统电量实现
BasicMessageChannel通信示例:
flutter端接收平台端系统电量方法
iOS端发送方法
Android端发送方法
遇到问题:需要dart,iOS,Android共同维护代码,代码重复率高,时间成本高。
iOS端最开始尝试解决方案,通过方法及参数,把字符串动态生成实例方法。比之前的代码强一点,但是还没有达到理想程度。
如何解决只只需在dart,iOS,Android三端维护一份代码,达到通信的需求呢?<