失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 【Flutter 混合开发】与原生通信-BasicMessageChannel

【Flutter 混合开发】与原生通信-BasicMessageChannel

时间:2019-01-21 20:50:19

相关推荐

【Flutter 混合开发】与原生通信-BasicMessageChannel

Flutter 混合开发系列 包含如下:

嵌入原生View-Android嵌入原生View-iOS与原生通信-MethodChannel与原生通信-BasicMessageChannel与原生通信-EventChannel添加 Flutter 到 Android Activity添加 Flutter 到 Android Fragment添加 Flutter 到 iOS

每个工作日分享一篇,欢迎关注、点赞及转发。

平台通信的3中方式

Flutter 与 Native 端通信有如下3个方法:

MethodChannel:Flutter 与 Native 端相互调用,调用后可以返回结果,可以 Native 端主动调用,也可以Flutter主动调用,属于双向通信。此方式为最常用的方式, Native 端调用需要在主线程中执行。BasicMessageChannel:用于使用指定的编解码器对消息进行编码和解码,属于双向通信,可以 Native 端主动调用,也可以Flutter主动调用。EventChannel:用于数据流(event streams)的通信, Native 端主动发送数据给 Flutter,通常用于状态的监听,比如网络变化、传感器数据等。

Flutter 端

Flutter 端创建MethodChannel通道,用于与原生端通信:

var channel = BasicMessageChannel('com.flutter.guide.BasicMessageChannel',StandardMessageCodec());

com.flutter.guide.BasicMessageChannel是 BasicMessageChannel 的名称,原生端要与之对应。

发送消息:

var result = await channel.send({'name': 'laomeng', 'age': 18});

参数类型任意,多个参数通常使用Map。返回Future,原生端返回的数据。

完整代码:

class BasicMessageChannelDemo extends StatefulWidget {@override_BasicMessageChannelDemoState createState() => _BasicMessageChannelDemoState();}class _BasicMessageChannelDemoState extends State<BasicMessageChannelDemo> {var channel = BasicMessageChannel('com.flutter.guide.BasicMessageChannel',StandardMessageCodec());var _data;@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(),body: Column(children: [SizedBox(height: 50,),RaisedButton(child: Text('发送数据到原生'),onPressed: () async {var result = await channel.send({'name': 'laomeng', 'age': 18});var name = result['name'];var age = result['age'];setState(() {_data = '$name,$age';});},),Text('原生返回数据:$_data'),],),);}}

Android 端

android 下创建BasicMessageChannelDemo

class BasicMessageChannelDemo(messenger: BinaryMessenger) : BasicMessageChannel.MessageHandler<Any> {private var channel: BasicMessageChannel<Any>init {channel = BasicMessageChannel(messenger, "com.flutter.guide.BasicMessageChannel", StandardMessageCodec())channel.setMessageHandler(this)}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)}}

onMessage方法在 Flutter 端调用 send 方法后调用,解析方法如下:

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)}

message是传入的参数,由于 Flutter 端传入的是 Map,所以上面的解析按照 Map 解析。reply.reply()是返回给 Flutter 的结果。

Flutter 端解析:

var result = await channel.send({'name': 'laomeng', 'age': 18});var name = result['name'];var age = result['age'];

两端的解析要相互对应。

MainActivity启动:

class MainActivity : FlutterActivity() {override fun configureFlutterEngine(flutterEngine: FlutterEngine) {super.configureFlutterEngine(flutterEngine)BasicMessageChannelDemo(flutterEngine.dartExecutor.binaryMessenger)flutterEngine.plugins.add(MyPlugin())}}

iOS 端

ios 下创建MethodChannelDemo,按如下方式:

import Flutterimport UIKitpublic class BasicMessageChannelDemo {var channel:FlutterBasicMessageChannelinit(messenger: FlutterBinaryMessenger) {channel = FlutterBasicMessageChannel(name: "com.flutter.guide.BasicMessageChannel", binaryMessenger: messenger)channel.setMessageHandler { (message, reply) inif let dict = message as? Dictionary<String, Any> {let name:String = dict["name"] as? String ?? ""let age:Int = dict["age"] as? Int ?? -1reply(["name":"hello,\(name)","age":age])}} } }

AppDelegate启动:

import UIKitimport Flutter@UIApplicationMain@objc class AppDelegate: FlutterAppDelegate {override func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {let controller : FlutterViewController = window?.rootViewController as! FlutterViewControllerMethodChannelDemo(messenger: controller.binaryMessenger)BasicMessageChannelDemo(messenger: controller.binaryMessenger)GeneratedPluginRegistrant.register(with: self)return super.application(application, didFinishLaunchingWithOptions: launchOptions)}}

原生端主动发送消息给Flutter

Flutter 端接收数据

@overridevoid initState() {super.initState();channel.setMessageHandler((message) {setState(() {_nativeData = message['count'];});});}

Android 发送数据

原生端启动定时器,每隔一秒向 Flutter 发送数据,Android 端代码:

class BasicMessageChannelDemo(var activity: Activity, messenger: BinaryMessenger) : BasicMessageChannel.MessageHandler<Any> {private var channel: BasicMessageChannel<Any>private var count = 0init {channel = BasicMessageChannel(messenger, "com.flutter.guide.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)}}

注意:Android 端发送数据要在主现场中调用,即:

activity.runOnUiThread {var map = mapOf("count" to count++)channel.invokeMethod("timer", map)}

启动修改如下:

class MainActivity : FlutterActivity() {override fun configureFlutterEngine(flutterEngine: FlutterEngine) {super.configureFlutterEngine(flutterEngine)BasicMessageChannelDemo(this,flutterEngine.dartExecutor.binaryMessenger)flutterEngine.plugins.add(MyPlugin())}}

iOS 发送数据

iOS 端启动定时器代码如下:

import Flutterimport UIKitpublic class BasicMessageChannelDemo {var channel:FlutterBasicMessageChannelvar count = 0init(messenger: FlutterBinaryMessenger) {channel = FlutterBasicMessageChannel(name: "com.flutter.guide.BasicMessageChannel", binaryMessenger: messenger)channel.setMessageHandler { (message, reply) inif let dict = message as? Dictionary<String, Any> {let name:String = dict["name"] as? String ?? ""let age:Int = dict["age"] as? Int ?? -1reply(["name":"hello,\(name)","age":age])}}startTimer()}func startTimer() {var timer = Timer.scheduledTimer(timeInterval:1, target: self, selector:#selector(self.tickDown),userInfo:nil,repeats: true)}@objc func tickDown(){count += 1var args = ["count":count]channel.sendMessage(args) { (reply) in}}}

交流

老孟Flutter博客(330个控件用法+实战入门系列文章):

欢迎加入Flutter交流群(微信:laomengit)、关注公众号【老孟Flutter】:

如果觉得《【Flutter 混合开发】与原生通信-BasicMessageChannel》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。