Flutter学习之原生通信BasicMessageChannel
本文主要介绍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])
}
}
}
}
之后在appDelegate
中注册channel
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
_ = BasicMessageChannelDemo(messenger: controller.binaryMessenger)
运行结果,发送了信息,原生端对数据处理后得到返回的结果
- 原生端主动发送消息给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
}
}
}
运行结果:
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)
运行结果
4. 小结
通过BasicMessageChannel
和原生端进行交互,通Send
和Reply
发送和响应。原理和我们的MethodChannel
类似。
用于使用指定的编解码器对消息进行编码和解码,属于双向通信
,可以客户端主动调用,也可以让Flutter
主动调用。另外要注意我们在客户端调用的时候要在主线程
进行调用。
转载自:https://juejin.cn/post/7113921320273838093