Flutter学习之原生通信BasicMessageChannel

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第28天,点击查看活动详情

本文主要介绍Flutter与原生通信-BasicMessageChannel,通过和android和iOS客户端进行交互。

1. flutter端

首先我们在flutter端页面创建一个通道进行通信

var messageChannel = const BasicMessageChannel('com.flutter.test.BasicMessageChannel',StandardMessageCodec());

通过messageChannel进行发送消息给原生客户端

Map? result = (await messageChannel.send({'name': 'Jack', 'age': 18})) as Map?;

多个参数使用map,因为是异步的所以我们使用async操作

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class BasicMessageChannelPage extends StatefulWidget {
  const BasicMessageChannelPage({Key? key}) : super(key: key);

  @override
  _BasicMessageChannelPageState createState() => _BasicMessageChannelPageState();
}

class _BasicMessageChannelPageState extends State<BasicMessageChannelPage> {
  var messageChannel = const BasicMessageChannel('com.flutter.test.BasicMessageChannel',StandardMessageCodec());

  var _data;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Column(
        children: [
          const SizedBox(
            height: 50,
          ),
          RaisedButton(
            child: const Text('发送数据到原生'),
            onPressed: () async {
              Map? result = (await messageChannel.send({'name': 'Jack', 'age': 18})) as Map?;
              var name = result!['name'];
              var age = result['age'];
              setState(() {
                _data = '$name,$age';
              });
            },
          ),
          Text('原生返回数据:$_data'),
        ],
      ),
    );
  }
}

2. iOS端

我们在iOS端创建一个类用于通信


import UIKit

import Flutter

class BasicMessageChannelDemo: NSObject {

    

    var channel:FlutterBasicMessageChannel

        

        init(messenger: FlutterBinaryMessenger) {

            channel = FlutterBasicMessageChannel(name: "com.flutter.test.BasicMessageChannel", binaryMessenger: messenger)

            channel.setMessageHandler { (message, reply) in

                if let dict = message as? Dictionary<String, Any> {

                    let name:String = dict["name"] as? String ?? ""

                    let age:Int = dict["age"] as? Int ?? 0

                    reply(["name":"hello,\(name)","age":age-1])

                }

            }

        }

}

image.png

之后在appDelegate中注册channel

let controller : FlutterViewController = window?.rootViewController as! FlutterViewController

 _ = BasicMessageChannelDemo(messenger: controller.binaryMessenger)

image.png

运行结果,发送了信息,原生端对数据处理后得到返回的结果

image.png

  • 原生端主动发送消息给Flutter
var _nativeData = '';
var _data ='';
@override
void initState() {
  super.initState();

  messageChannel.setMessageHandler(( Object? message) async {
    setState(() {
      final Map args = (message as Map)!;

      _nativeData =  args['count'];
    });
  });
}

我们在iOS中添加一个定时器

import UIKit

import Flutter


class BasicMessageChannelDemo {

    var count =  0

    var channel:FlutterBasicMessageChannel

    var timer :Timer!  

    init(messenger: FlutterBinaryMessenger) {
    
        channel = FlutterBasicMessageChannel(name: "com.flutter.test.BasicMessageChannel", binaryMessenger: messenger)

        channel.setMessageHandler { (message, reply) in

            if let dict = message as? Dictionary<String, Any> {

                let name:String = dict["name"] as? String ?? ""

                let age:Int = dict["age"] as? Int ?? 0

                reply(["name":"hello,\(name)","age":age-1])

            }
             self.startTimer()
        }

    }

    func startTimer() {

        timer = Timer.scheduledTimer(timeInterval:1, target: self, selector:#selector(self.tickDown),userInfo:nil,repeats: true)

    }

    @objc func tickDown(){

        count += 1

        let args = ["count":count]

        channel.sendMessage(args) {(reply) in

        }

    }

}

运行结果: image.png

3. android端

android端也是类似,我们创建一个BasicMessageChannelDemo

package com.example.flutter_android_view

import android.app.Activity
import io.flutter.plugin.common.BasicMessageChannel
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.StandardMessageCodec
import java.util.*
import kotlin.concurrent.timerTask

class BasicMessageChannelDemo(var activity: Activity, messenger: BinaryMessenger) : BasicMessageChannel.MessageHandler<Any> {

    private var channel: BasicMessageChannel<Any>
    private var count = 0

    init {
        channel = BasicMessageChannel(messenger, "com.flutter.test.BasicMessageChannel", StandardMessageCodec())
        channel.setMessageHandler(this)
        startTimer()
    }


    fun startTimer() {
        var timer = Timer().schedule(timerTask {
            activity.runOnUiThread {
                var map = mapOf("count" to count++)
                channel.send(map,object :BasicMessageChannel.Reply<Any>{
                    override fun reply(reply: Any?) {

                    }
                })
            }
        }, 0, 1000)

    }

    override fun onMessage(message: Any?, reply: BasicMessageChannel.Reply<Any>) {
        val name = (message as Map<String, Any>)["name"]
        val age = (message as Map<String, Any>)["age"]

        var map = mapOf("name" to "hello,$name",
            "age" to "$age"
        )

        reply.reply(map)
    }
}

MainActivity中添加BasicMessageChannel

BasicMessageChannelDemo(this,flutterEngine.dartExecutor.binaryMessenger)

运行结果

image.png

4. 小结

通过BasicMessageChannel和原生端进行交互,通SendReply发送和响应。原理和我们的MethodChannel类似。 用于使用指定的编解码器对消息进行编码和解码,属于双向通信,可以客户端主动调用,也可以让Flutter主动调用。另外要注意我们在客户端调用的时候要在主线程进行调用。

猜你喜欢

转载自juejin.im/post/7113921320273838093