Flutter 鸿蒙化 使用 Flutter Channel实现和Flutter和HarmonyOS交互

2,032 阅读2分钟

前言导读

今天这节课我们讲一下 flutter和我们的HarmonyOS交互。

作用

我们在现有的Flutter开发中 肯定会遇到各种Flutter实现不了的功能 这时候我们就需要原生native 端来帮忙 。我们就要桥接。来实现我们原生实现不了的功能,例如我们获取设备id。网络状态等等,还有Flutter透传到鸿蒙next 端。然后回调回来的数据。

三种方式交互

  • 1 MethodChannel 方式

  • 2 BasicMessageChannel 方式

  • 3 EventChannel 方式

如何使用 Flutter Channel

MethodChannel

flutter 端代码
final _platform = const MethodChannel('samples.flutter.dev/battery');

 //调用鸿蒙next 方法
  Future<void> _getBatteryLevel() async {
    String batteryLevel;
    try {
      // 调用需要在平台中实现的方法
      final result = await _platform.invokeMethod<int>('getBatteryLevel');
      batteryLevel = '获取等级 $result % .';
    } on PlatformException catch (e) {
      batteryLevel = "Failed to get battery level: '${e.message}'.";
    }

    setState(() {
      message = batteryLevel;
    });
  }

鸿蒙next端代码
onAttachedToEngine(binding: FlutterPluginBinding): void {
  this.channel = new MethodChannel(binding.getBinaryMessenger(), "samples.flutter.dev/battery");
  let that = this;
  this.channel.setMethodCallHandler({
    async onMethodCall(call: MethodCall, result: MethodResult) {
      switch (call.method) {
        case "getBatteryLevel":
          that.api.getBatteryLevel(result);
          break;
        default:
          result.notImplemented();
          break;
      }
    }
  })
  
 class BatteryApi {
 async  getBatteryLevel(result: MethodResult) {
   result.success(100);
 }

EventChannel

flutter 端代码
String getString="";
  _initListener() {
    _eventChannel.receiveBroadcastStream().listen((event) {
      setState(() {
        getString = "设备号=$event";
      });
    });
  }
  
  
  _testStreamCall() async {
    try {
      await _platform.invokeMethod('callEvent');
    } on PlatformException catch (e) {
      print(e);
    }
  }
鸿蒙next端代码
 private eventSink?: EventSink;
this.eventChannel = new EventChannel(binding.getBinaryMessenger(), "samples.flutter.dev/event_channel");
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);
  }
});


  onAttachedToEngine(binding: FlutterPluginBinding): void {
    this.channel = new MethodChannel(binding.getBinaryMessenger(), "samples.flutter.dev/battery");
    let that = this;
    this.channel.setMethodCallHandler({
      async onMethodCall(call: MethodCall, result: MethodResult) {
        switch (call.method) {
          case "callEvent":
            let deviceid = await DeviceUtil.getDeviceId(false,"") as string;
            that.eventSink?.success(deviceid);
            break;
        }
      }
    })

BasicMessageChannel 方式

dart代码
  String getinputString="";
  String  fluttertonextstr="";;
_testBasicChannel() async {
  String result;
  try {
    result = await _basicChannel.send(fluttertonextstr) as String;
  } on PlatformException catch (e) {
    result = "Error: $e";
  }
  setState(() {
    getinputString = "透传回来的数据 = "+result;
  });
}
    Row(
            children: <Widget>[
              Container(
                alignment: Alignment.center,
                width: 100,
                height: 50,
                child: Text("透传:"),
              ),
              Expanded(
                child: TextField(
                  obscureText: false,
                  decoration: InputDecoration(
                    hintText: "请求输入传给鸿蒙的数据",
                    border: InputBorder.none,
                  ),
                  onChanged: (value){
                    setState(() {
                      this.fluttertonextstr=value;
                    });
                  },
                ),
              )
            ],),
          ElevatedButton(
            onPressed: () => _testBasicChannel(),
            child: const Text("获取Flutter透传数据"),
          ),
          Text(getinputString),
鸿蒙next端代码
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);
    reply.reply(message);
  }
})

效果图

88823b7d5e4be475d2ff14feced9923

31b7b2cb736503a3ea13a59fe5a0d0f

dd898e36be918a735478245024bd918

总结

观察上面的效果图我们发现再Flutter 和鸿蒙next的交互中我们有3种方式,我们可以通过 MethodChannel 或者 BasicMessageChannel 能够调到鸿蒙next端代码也可以通过 EventChannel 来传递参数给到鸿蒙next这边 然后通过next回调给我们的flutter 端完成一个透传的效果 .只要我们掌握了Flutter to Harmonyos next 中channel 能力我们就可以实现功能逻辑的,桥接 使得原本Flutter不支持的功能我们也能够实现 例如和原生鸿蒙next交互获取设备id 网络状态等等一些手机硬件信息。有更多想要学习的可以关注我的B站课程