精选文章

Flutter + 原生通信

2025-08-21 · 通信

Flutter 与原生通信的难点不在“调用”,而在协议、稳定性与可维护性。本文用一套可直接复用的代码范式,讲清 MethodChannel / EventChannel 的正确打开方式。

1. 先定义通信协议(最关键)

不要让 Flutter 与原生“随意传参”,必须先定义协议:

{
  "action": "getDeviceInfo",
  "payload": {}
}

以及统一响应:

{
  "ok": true,
  "code": 0,
  "message": "",
  "data": {"model": "..."}
}

这样才能避免双方升级时互相“猜数据”。

2. Flutter 侧:封装成可测试的服务层

class NativeBridge {
  static const MethodChannel _channel = MethodChannel('app/native');

  static Future<Map<String, dynamic>> getDeviceInfo() async {
    final res = await _channel.invokeMethod('getDeviceInfo');
    return Map<String, dynamic>.from(res as Map);
  }
}

建议再封一层 ApiResponse,统一错误处理。

3. Android 侧:统一入口处理

class MainActivity: FlutterActivity() {
  private val CHANNEL = "app/native"

  override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
    super.configureFlutterEngine(flutterEngine)
    MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
      .setMethodCallHandler { call, result ->
        when (call.method) {
          "getDeviceInfo" -> {
            val info = mapOf("model" to Build.MODEL)
            result.success(info)
          }
          else -> result.notImplemented()
        }
      }
  }
}

核心:所有原生处理集中到一个入口,避免散落。

4. iOS 侧:保持与 Android 对齐

let channel = FlutterMethodChannel(name: "app/native", binaryMessenger: controller.binaryMessenger)
channel.setMethodCallHandler { call, result in
  switch call.method {
  case "getDeviceInfo":
    result(["model": UIDevice.current.model])
  default:
    result(FlutterMethodNotImplemented)
  }
}

保持方法名与返回结构一致,是长期维护的关键。

5. EventChannel:处理持续事件流

例如原生监听网络变化或传感器数据:

Flutter 侧:

static const EventChannel _event = EventChannel('app/events');
static Stream<dynamic> get events => _event.receiveBroadcastStream();

原生侧:

  • Android: EventChannel + StreamHandler
  • iOS: FlutterEventChannel + FlutterStreamHandler

原则:事件流必须可取消,避免内存泄漏。

6. 常见错误与规避

  • Method 名称不一致 → 必须统一定义常量
  • 返回结构不一致 → 统一响应协议
  • 异常未捕获 → 所有调用包 try/catch
  • 长时任务阻塞 UI → 放到原生线程池

7. 实践清单

  • 定义统一协议与错误码
  • Flutter 侧封装服务层
  • 原生侧集中处理入口
  • EventChannel 订阅可取消
  • 双端结构一致

总结

Flutter + 原生通信不是“能调通就行”,而是一个小型系统:协议、入口、错误、事件流必须清晰。只要规范到位,这一层的维护成本会非常低。

JJ

作者简介

专注于内容创作、产品策略与设计实践。欢迎交流合作。

上一篇 下一篇