持续创作,加速成长!这是我参与「日新计划 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])
        }
      }
    }
}

Flutter学习之原生通信BasicMessageChannel

之后在appDelegate中注册channel

let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
 _ = BasicMessageChannelDemo(messenger: controller.binaryMessenger)

Flutter学习之原生通信BasicMessageChannel

运转成果,发送了信息,原生端对数据处理后得到回来的成果

Flutter学习之原生通信BasicMessageChannel

  • 原生端自动发送音讯给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
    }
  }
}

运转成果:

Flutter学习之原生通信BasicMessageChannel

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)

运转成果

Flutter学习之原生通信BasicMessageChannel

4. 小结

经过BasicMessageChannel和原生端进行交互,通SendReply发送和响应。原理和咱们的MethodChannel类似。 用于运用指定的编解码器对音讯进行编码和解码,归于双向通信,能够客户端自动调用,也能够让Flutter自动调用。另外要注意咱们在客户端调用的时分要在线程进行调用。