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;  @override  Widget 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:FlutterBasicMessageChannel        init(messenger: FlutterBinaryMessenger) {        channel = FlutterBasicMessageChannel(name: "com.flutter.guide.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 ?? -1                reply(["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! FlutterViewController    MethodChannelDemo(messenger: controller.binaryMessenger)    BasicMessageChannelDemo(messenger: controller.binaryMessenger)    GeneratedPluginRegistrant.register(with: self)    return super.application(application, didFinishLaunchingWithOptions: launchOptions)  }}

原生端被动发送音讯给Flutter

Flutter 端接收数据
@override  void 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 = 0    init {        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:FlutterBasicMessageChannel    var count =  0        init(messenger: FlutterBinaryMessenger) {        channel = FlutterBasicMessageChannel(name: "com.flutter.guide.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 ?? -1                reply(["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 += 1        var args = ["count":count]        channel.sendMessage(args) { (reply) in                    }    }}

交换

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

欢送退出Flutter交换群(微信:laomengit)、关注公众号【老孟Flutter】: