Flutter项目和鸿蒙平台的通信

Flutter项目和鸿蒙平台的通信

前言

大家在使用Flutter开发项目的时候, Flutter提供了Platfrom Channel API来和个个平台进行交互。

Flutter官方目前提供了一下三种方式来和个个平台交互:

  • BasicMessageChannel:用于传递字符串和半结构化的信息。BasicMessageChannel支持数据双向传递,有返回值。
  • MethodChannel:用于传递方法调用(method invocation)。MethodChannel支持数据双向传递,有返回值。通常用来调用 native 中某个方法
  • EventChannel: 用于数据流(event streams)的通信。 EventChannel仅支持数据单向传递,无返回值。有监听功能,比如电量变化之后直接推送数据给flutter端
    对比表格:

    flutter_flutter 也是通过上述三种方式来和鸿蒙平台进行通信的

Flutter和Harmonyos通信

MethodChannel

  • flutter代码:
dart 复制代码
// 创建一个通道
final _platform = const MethodChannel('samples.flutter.dev/battery');

Future<void> _getBatteryLevel() async {
    String batteryLevel;
    try {
      // getBatteryLevel 是flutter传递给鸿蒙平台的参数
      final result = await _platform.invokeMethod<int>('getBatteryLevel');
      batteryLevel = 'Battery level at $result % .';
    } on PlatformException catch (e) {
      batteryLevel = "Failed to get battery level: '${e.message}'.";
    }
  }

鸿蒙平台代码:

typescript 复制代码
// 实现这个声明周期方法,在plugin中
onAttachedToEngine(binding: FlutterPluginBinding): void {
// 创建一个通道, 通道名称需要和flutter创建的通道名称保持一致,才可以通信
    this.channel = new MethodChannel(binding.getBinaryMessenger(), "samples.flutter.dev/battery");
    let that = this;
  	// 实现通道的回调方法
    this.channel.setMethodCallHandler({
      onMethodCall(call: MethodCall, result: MethodResult) {
        switch (call.method) {
        // 接收到flutter传递过来的参数
          case "getBatteryLevel":
          	// 执行对应的方法, 然后把结果传递给flutter
            that.api.getBatteryLevel(result);
            break;
          default:
            result.notImplemented();
            break;
        }
      }
    })  
  }

// 获取电池电量的类
class BatteryApi {
  getBatteryLevel(result: MethodResult) {
    let level: number = batteryInfo.batterySOC;
    Log.i(TAG, "level=" + level);
    let wrapped: Map<String, Any> = new Map<String, Any>();
    if (level >= 0) {
      result.success(level);
    } else {
      Log.i(TAG, "getBatteryLevel else");
      wrapped.set("UNAVAILABLE", "Battery level not available.");
      result.error("UNAVAILABLE", "Battery level not available.", null)
    }
    Log.i(TAG, "getBatteryLevel finish");
  }
}

BasicMessageChannel

Flutter代码:

typescript 复制代码
// 创建一个基础通道, 通道名需要和鸿蒙平台约定好
final _basicChannel = const BasicMessageChannel(
      "samples.flutter.dev/basic_channel", StandardMessageCodec());
      _testBasicChannel() async {
    String result;
    try {
      result = await _basicChannel.send(++count) as String;
    } on PlatformException catch (e) {
      result = "Error: $e";
    }
    setState(() {
      message = result;
    });
  }

鸿蒙平台代码:

typescript 复制代码
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

flutter代码:

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

鸿蒙平台代码:

typescript 复制代码
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());
相关推荐
LinXunFeng1 小时前
拿竞品 App 一扫,技术栈全暴露了
android·flutter·开源
Sirius_Ji6 小时前
# 一份鸿蒙原生支持硬解的 ffmpeg 开发基座
harmonyos
贾伟康7 小时前
HarmonyOS API 26 Navigation路由栈上限:stackSizeLimit、过载保护与容量观测
harmonyos·arkts·navigation·navpathstack·api26
江华森12 小时前
把鸿蒙云手机调试的 5 个坑写成 Skill:12 项检查清单与报错决策树
harmonyos
木木子2213 小时前
用华为云码道构建校园导航应用「新生通」:从需求分析到工程落地
华为·华为云·harmonyos
传奇开心果编程14 小时前
【Flutter踩坑排雷】第28课:平台目录缺失与修复坑|`flutter create` 的“重建”与“覆盖”边界
android·flutter·ios·移动开发·跨平台·dart·声明式ui
贾伟康14 小时前
HarmonyOS API 26 Navigation 自适应模式:mode、分栏切换与窗口断点治理
harmonyos·arkts·arkui·navigation·自适应布局
贾伟康15 小时前
【转盘决定吧|07】HarmonyOS ArkTS 6.0.2.130 趣味题库:场景分类、随机选择与详情页解耦
harmonyos·arkts·路由·数据建模·arkui
贾伟康15 小时前
【电路实验模拟|03】HarmonyOS ArkTS 交通灯实战:用定时状态切换红黄绿灯
harmonyos·arkts·canvas·arkui·交通灯
程序员老刘·1 天前
Flutter 3.50更新,开发者应该关注什么?
flutter·ai编程·跨平台开发