Flutter与Native通信(三)BasicMessageChannel

07/23/2022 10:06 上午 posted in  Flutter

flutter可以native之间可以通过Platform Channels APIs进行通信,API主要有以下三种:

  • [MethodChanel]:用于传递方法调用(method invocation)
  • [EventChannel]:用于事件流的发送(event streams)
  • [BasicMessageChannel]:用于传递字符串和半结构化的消息

BasicMessageChannel用于在flutter和native互相发送消息,一方给另一方发送消息,收到消息之后给出回复。照例我们先看一下API的基本使用流程,然后再看代码实现

1.BasicMessageChannel的基本流程

flutter向native发送消息

  1. [flutter]创建BasicMessageChannel
  2. [native]通过BasicMessageChannel#MessageHandler注册Handler
  3. [flutter]通过BasicMessageChannel#send发送消息
  4. [native]BasicMessageChannel#MessageHandler#onMessage中接收消息,然后reply

native向flutter发送消息

流程也是一样的,只是将[flutter]与[native]反调

2.代码实现

flutter端

flutter需要完成以下工作

  • 创建BasicMessageChannel
  • 通过BasicMessageChannel#send发送消息

相对与其他Channel类型的创建,MessageChannel的创建除了channel名以外,还需要指定编码方式:

BasicMessageChannel(String name, MessageCodec<T> codec, {BinaryMessenger binaryMessenger})

发送的消息会以二进制的形式进行处理,所以要针对不同类型的数进行二进制编码

编码类型 消息格式
BinaryCodec 发送二进制消息时
JSONMessageCodec 发送Json格式消息时
StandardMessageCodec 发送基本型数据时
StringCodec 发送String类型消息时
class _MyHomePageState extends State<MyHomePage> {
  static const _channel = BasicMessageChannel('com.example.messagechannel/interop', StringCodec());
 
  String _platformMessage;
 
  void _sendMessage() async {
    final String reply = await _channel.send('Hello World form Dart');
    print(reply);
  }
 
  @override
  initState() {
    super.initState();
 
    // Receive messages from platform
    _channel.setMessageHandler((String message) async {
      print('Received message = $message');
      setState(() => _platformMessage = message);
      return 'Reply from Dart';
    });
 
    // Send message to platform
    _sendMessage();
  }

native(android)端

  • android端完成以下工作:
  • 创建BasicMessageChannel
  • 通过setHandler注册MessageHandler
  • MessageHandler#onMessage回调中接收到message后,通过reply进行回复
class MainActivity: FlutterActivity() {
    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        GeneratedPluginRegistrant.registerWith(flutterEngine)
 
        val channel = BasicMessageChannel(
                flutterEngine.dartExecutor.binaryMessenger,
                "com.example.messagechannel/interop",
                StringCodec.INSTANCE)
 
        // Receive messages from Dart
        channel.setMessageHandler { message, reply ->
            Log.d("Android", "Received message = $message")
            reply.reply("Reply from Android")
        }
 
        // Send message to Dart
        Handler().postDelayed({
            channel.send("Hello World from Android") { reply ->
                Log.d("Android", "$reply")
            }
        }, 500)
    }
}

Andorid端回复的消息会在Flutter端显示