Flutter 如何高效与Android 原生通信

7 阅读3分钟

Flutter 凭借其高效的渲染性能和跨平台能力,已成为移动开发的热门选择。然而,在实际应用中,我们往往需要访问平台特定的硬件或系统服务,例如 WiFi 扫描、设备信息获取、无人机遥控器等。此时,Flutter 必须与 Android 原生代码进行通信。本文通过分析一个真实的无人机控制应用的反编译代码,详细阐述 Flutter 与 Android 原生通信的核心机制与实现方式。

1、Flutter 与原生通信的三种基本方式

Flutter 官方提供了三个核心接口用于平台通信:

  1. MethodChannel:用于 Flutter 调用原生方法,并接收返回值(一次调用,一次返回)。

  2. EventChannel:用于原生向 Flutter 持续发送数据流(如传感器数据、网络状态变化)。

  3. BasicMessageChannel:用于简单的异步消息传递,支持自定义编解码器。 在实际项目中,MethodChannelEventChannel 使用最为频繁。

2、以 WiFi 扫描插件为例:MethodChannel 实战

在反编译的代码中,dev/flutternetwork/wifi/wifi_scan/WifiScanPlugin.java 是一个典型的 WiFi 扫描插件。其工作流程如下:

  • 注册通道:在 onAttachedToEngine 方法中,插件会创建一个名为 "dev.flutternetwork/wifi_scan"MethodChannel,并设置 MethodCallHandler

  • 处理调用:当 Flutter 端调用 scan()getScanResults() 时,原生端根据 call.method 执行对应逻辑:

  - 通过 WifiManager 调用 startScan() 发起扫描。

  - 注册 BroadcastReceiver 监听 SCAN_RESULTS_AVAILABLE_ACTION 广播,异步获取扫描结果。

  - 将结果(SSID、BSSID、信号强度等)封装成 List<Map>,通过 result.success() 返回给 Flutter。

  • 权限处理:插件还会检查 ACCESS_FINE_LOCATION 等权限,确保扫描能够正常进行。 这种模式完美体现了 MethodChannel 的特点:Flutter 发起请求,原生执行操作并返回结果

3、EventChannel 示例:网络状态实时监测

dev/fluttercommunity/plus/connectivity/ConnectivityPlugin.java 展示了 EventChannel 的用法。该插件需要持续监听网络连接状态的变化(WiFi 连接、断开、切换移动网络等)。

  • 注册 EventChannel:创建名为 "dev.fluttercommunity.plus/connectivity"EventChannel,并设置 StreamHandler

  • 启动监听:在 onListen 回调中,注册 BroadcastReceiver 监听 CONNECTIVITY_ACTION 广播。每当网络状态变化时,通过 eventSink.success() 将新的网络类型(如 "wifi""mobile""none")发送给 Flutter。

  • 停止监听:在 onCancel 回调中,注销广播接收器,释放资源。 这种 事件流 模式非常适合传感器、定位、网络变化等需要持续推送数据的场景。

4、集成自定义 SDK:无人机控制中的通信设计

在上述无人机控制应用中,除了 Flutter 插件外,还存在一个庞大的原生 SDK(rcsdk 目录)。该 SDK 负责与无人机硬件进行 USB/串口通信、协议解析、飞行控制等。那么,Flutter 如何调用这个 SDK 的功能? 通常的设计方案是:

  1. 封装原生 SDK:创建一个 Flutter 插件(如 RCSDKPlugin),在内部持有 RCSDKManager 实例。

  2. 暴露方法:通过 MethodChannel 暴露 connect(), disconnect(), takeOff(), setGimbalAngle() 等方法。

  3. 数据回调:对于飞控状态、图传数据等实时信息,使用 EventChannel 将数据流源源不断地推送给 Flutter 层。

  4. 线程管理:由于 USB 通信、数据解析等操作耗时且频繁,原生端需在子线程执行,避免阻塞 UI 线程。

5、总结

Flutter 与 Android 原生的通信机制清晰且强大:

  • MethodChannel 实现单向请求-响应,适用于 WiFi 扫描、设备信息获取等功能。

  • EventChannel 实现原生到 Flutter 的数据流推送,适用于网络状态、传感器数据等。

  • 插件化封装 将复杂的原生 SDK 隐藏在插件内部,为 Flutter 提供简洁的 Dart API。