Flutter Channel 原理与鸿蒙原生对接

2025-03-12 08:44:11
179次阅读
0个评论

本文介绍在Flutter OpenHarmony化工程中,如何使用 Flutter Channel 能力。

Flutter Channel 原理与鸿蒙原生对接

一、Flutter Channel 核心能力解析

Flutter Channel 是 Flutter 与原生平台进行双向通信的核心桥梁,支持三种不同类型的通道:

通道类型 数据传输方向 典型应用场景
MethodChannel 双向请求/响应 调用原生API、获取设备信息
EventChannel 单向数据流 持续监听传感器、网络状态
BasicMessageChannel 双向消息传递 结构化数据交换(JSON/二进制)

核心原理:通过 Platform Thread 与 Dart VM 的交互,实现跨平台消息编解码

二、鸿蒙原生对接实战

开发环境准备

  • Flutter 3.21+
  • vscode
  • 鸿蒙API Version 12+

1. MethodChannel 示例:获取鸿蒙设备信息

Flutter 端

// 创建MethodChannel
const channel = MethodChannel('com.example/device');

Future<String> getHarmonyOSVersion() async {
  try {
    return await channel.invokeMethod('getOSVersion');
  } catch (e) {
    return 'Unknown';
  }
}

2. EventChannel 示例:实时获取陀螺仪数据

Flutter 端

final eventChannel = EventChannel('com.example/sensors');

Stream<GyroscopeData> getGyroscopeStream() {
  return eventChannel
      .receiveBroadcastStream()
      .map((data) => GyroscopeData.fromMap(data));
}

三、常见问题排查

  1. 通道未注册:检查通道名称是否两端一致
  2. 数据类型不匹配:使用StandardMethodCodec进行调试
  3. 内存泄漏:确保EventChannel的Stream及时关闭
  4. 线程崩溃:原生代码必须进行空安全判断

四、扩展应用场景

  • 调用鸿蒙AI能力(图像识别、语音助手)
  • 集成华为地图服务
  • 使用鸿蒙分布式能力
  • 访问系统级功能(多屏协同、平行视界)

五、总结

通过Flutter Channel,开发者可以:

✅ 复用80%的Dart代码 ✅ 灵活调用20%的鸿蒙特色功能 ✅ 实现真正的跨平台融合开发

参考文档:

以下是关键实现代码,完整的demo请参考 channel_demo

MethodChannel

dart代码

// 创建实例
final _platform = const MethodChannel('samples.flutter.dev/battery');
// 调用方法 getBatteryLevel
final result = await _platform.invokeMethod<int>('getBatteryLevel');

ets代码

onAttachedToEngine(binding: FlutterPluginBinding): void {
    let that = this;
    // 创建实例
    this.channel = new MethodChannel(binding.getBinaryMessenger(), "samples.flutter.dev/battery");
    // 设置回调,调用具体的实现
    this.channel.setMethodCallHandler({
        onMethodCall(call: MethodCall, result: MethodResult) {
        switch (call.method) {
            case "getBatteryLevel":
                that.api.getBatteryLevel(result);
            break;
            default:
                result.notImplemented();
            break;
        }
        }
    })
}

BasicMessageChannel

dart代码

int count = 0;
// 创建实例
final _basicChannel = const BasicMessageChannel(
      "samples.flutter.dev/basic_channel", StandardMessageCodec());
// 调用方法,获取平台侧的返回值
String result = await _basicChannel.send(++count) as String;

ets代码

onAttachedToEngine(binding: FlutterPluginBinding): void {
    // 创建实例
    this.basicChannel = new BasicMessageChannel(binding.getBinaryMessenger(), "samples.flutter.dev/basic_channel", new StandardMessageCodec());
    // 设置回调,调用具体的实现
    this.basicChannel.setMessageHandler({
        onMessage(message: Any, reply: Reply<Any>) {
        Log.i(TAG, "message=" + message);
        if (message % 2 == 0) {
            reply.reply("run with if case.");
        } else {
            reply.reply("run with else case");
        }
        }
    })
}

EventChannel

dart代码

// 创建实例
final _eventChannel = const EventChannel('samples.flutter.dev/event_channel');
// 注册事件监听
_eventChannel.receiveBroadcastStream().listen((event) {
    setState(() {
        message = "EventChannel event=$event";
    });
});

ets代码

private eventSink?: EventSink;

onAttachedToEngine(binding: FlutterPluginBinding): void {
    let that = this;
    // 创建实例
    this.eventChannel = new EventChannel(binding.getBinaryMessenger(), "samples.flutter.dev/event_channel");
    // 设置回调,获取EventSink
    this.eventChannel.setStreamHandler({
        onListen(args: Any, events: EventSink): void {
            that.eventSink = events;
            Log.i(TAG, "onListen: " + args);
        },
        onCancel(args: Any): void {
            that.eventSink = undefined;
            Log.i(TAG, "onCancel: " + args);
        }
    });
}

// ...
// 使用 EventSink 发送数据后,dart断的事件监听回调会收到发送的数据。
that.eventSink?.success("Success at " + new Date());
收藏01

登录 后评论。没有帐号? 注册 一个。