本课时介绍 Flutter 如何与原生平台进行通信交互方式,让 Flutter 支持各种原生平台的基础能力。
使用场景
由于 Flutter 是一个跨平台 UI 库,因此不支持原生系统的功能,例如:
-
系统通知;
-
系统感应、相机、电量、LBS、声音、语音识别;
-
分享、打开其他 App 或者打开自身 App;
-
设备信息、本地存储。
以上只列举了部分,其实主要是和系统服务调用相关的功能,大部分都不支持。这时候就需要原生平台提供一些基础服务给 Flutter 来调用。我们先来看下 Flutter 与 Android 和 iOS 是怎么进行消息传递和接收的。
交互原理
在 Flutter 中存在三种与原生平台进行交互的方法: MethodChannel 、BasicMessageChannel 和 EventChannel 。这三者在底层是没有区别的,都是基于 binaryMessenger 来实现。不过在应用层中的使用场景有所区别。
-
MethodChannel ,该方法需要创建一个消息通道句柄,然后再利用其中的 invokeMethod 来调用原生平台,原生平台根据传递的方法和参数,执行并获得具体的异步响应结果。该方法支持两个参数,一个是方法名,一个是方法参数,因此更适合去调用原生客户端的函数方法;
-
BasicMessageChannel ,该方法需要创建一个消息通道句柄,然后再利用其中的 send 方法发送数据给到原生平台.原生平台接收到数据后,可以针对接收数据响应返回,也可以在接收数据后,不做任何返回。因此该方法更适合向原生平台传递数据,而不是功能调用;
-
EventChannel ,该方法是数据流传递,适用于大文件或者数据流媒体等的应用。发送方不会有响应,但是它会通过调用 MethodChannel 来通知原生平台,比如开始监听数据接收会发送 listen ,取消了数据接收会发送 cancel。
在实际应用中三种方法都是有一定场景,大部分情况下还是基于 MethodChannel 来实现,比如前面我们所应用到的插件:FlutterWebviewPlugin 和 PathProviderPlugin ,当然其中也涉及 EventChannel 的应用,比如 UniLinksPlugin 插件。接下来我们具体看下整个消息交互的流转过程。
交互实现过程
根据官网的知识以及我自己的一个理解,可以将整个过程总结为下图 1 。
图 1 消息交互流程图
从图 1 中我们可以看到,所有的消息都是通过 binaryMessenger 来传递,Flutter 的底层是 C 和 C++ 实现的,binaryMessenger 就是通过 C++ 底层库来调用平台相关的功能,数据返回也是原路处理返回。上面的调用过程,就是 Flutter 官网三层架构(如图 2 所示)的一个典型例子。
图 2 Flutter 三层架构
应用示例
原理分析清晰后,我们再基于我们当前 Two You Friend App 项目实践一下这个功能。主要需求就是能够在 Flutter 中查看当前电量信息,具体效果如如图 3 所示。
图 3 获取电量界面效果图
从图中我们可以看到在 Android 中是可以正常获取到当前电量信息,但是在 iOS 中是无法获取(主要原因是在虚拟机上 iOS 不支持 device.batteryState 方法)。接下来我们看下具体的代码实现逻辑。
增加测试页面
在项目中的 lib/pages 下创建一个 test_page 文件夹,在文件夹中创建 index.