Flutter提供了一套Platform Channel的机制,来满足Flutter与Native通信的需求。
三种通信方式
1. EventChannel: 是一种native向flutter发送数据的单向通信方式,flutter无法返回任何数据给native。主要用于native向flutter发送手机电量变化、网络连接变化、陀螺仪、传感器等。
2. BaseMessageChannel : 用于传递字符串和半结构化的信息(在大内存数据块传递的情况下使用)。
3. MethodChannel: 支持数据双向传递,有返回值。
这三种方式适用的场景:MethodChannel用于native与flutter的方法调用,EventChannel用于native单向的向flutter发送广播消息,BasicMessageChannel用于native与flutter之间的消息互发。
编码环境:系统:wind10,开发工具:androidstudio 2022,flutter版本:3.7.8
基于混合开发模式,flutter作为module使用。
1,MethodChannel的实现
android端创建FlutterBridge管理类代码如下:
import android.util.Log
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
/**
* Flutter和Native通信插件
*/
open class FlutterBridge : MethodCallHandler {
private var methodChannels = mutableListOf<MethodChannel>()
companion object {
@JvmStatic
var instance: FlutterBridge? = null
private set
@JvmStatic
fun init(flutterEngine: FlutterEngine): FlutterBridge? {
val methodChannel = MethodChannel(
flutterEngine.dartExecutor,
"MethodChannel"
)
if (instance == null) {
FlutterBridge().also { instance = it }
}
methodChannel.setMethodCallHandler(instance)
//因多FlutterEngine后每个FlutterEngine需要单独注册一个MethodChannel,所以用集合将所有的MethodChannel保存起来
instance!!.apply {
methodChannels.add(methodChannel)
}
return instance
}
}
/**
* 发送数据
* method:方法名
* arguments:数据
*/
fun fire(method: String, arguments: Any?) {
methodChannels.forEach {
it.invokeMethod(method, arguments)
}
}
/**
* 发送数据
* method:方法名
* arguments:数据
* callback:回调
*/
fun fire(method: String, arguments: Any?, callback: MethodChannel.Result?) {
methodChannels.forEach {
it.invokeMethod(method, arguments, callback)
}
}
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { //处理来自Dart的方法调用
Log.e(javaClass.simpleName, "onMethodCall: methodName=" + call.method+",name="+call.arguments)
}
}
在Application中进行初始化:
package com.example.flutter_demo
import FlutterBridge
import android.app.Application
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.embedding.engine.FlutterEngineCache
import io.flutter.embedding.engine.dart.DartExecutor
open class BaseApplication : Application() {
private lateinit var mFlutterEngine: FlutterEngine;
override fun onCreate() {
super.onCreate()
//提前预加载Flutter模块,能够快速的启动。
mFlutterEngine = FlutterEngine(this)
mFlutterEngine.dartExecutor.executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault())
FlutterEngineCache.getInstance().put("engine_id", mFlutterEngine)
//初始化FlutterBridge
FlutterBridge.init(mFlutterEngine)
}
override fun onTerminate() {
mFlutterEngine.destroy();
super.onTerminate()
}
}
安卓端调用:
package com.example.flutter_demo
import FlutterBridge
import android.annotation.SuppressLint
import android.os.Bundle
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import io.flutter.embedding.android.FlutterActivity
class MainActivity : AppCompatActivity() {
@SuppressLint("MissingInflatedId")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<Button>(R.id.btn).setOnClickListener {
//启动flutter模块
startActivity(
FlutterActivity.withCachedEngine("engine_id").build(this)
)
}
findViewById<Button>(R.id.send).setOnClickListener {
//发送一个方法名为update的数据,并带有回调。
FlutterBridge.instance?.fire("update","发送数据到flutter")
}
}
}
flutter端创建管理类:
import 'package:flutter/services.dart';
///Flutter通信框架
class FlutterBridge {
static final FlutterBridge _instance = FlutterBridge._();
final MethodChannel _bridge = const MethodChannel('MethodChannel');
final _listeners = {};
FlutterBridge._() {
_bridge.setMethodCallHandler((MethodCall call) {
String method = call.method;
if (_listeners[method] != null) {
return _listeners[method](call);
}
return Future.value("FlutterBridge返回");
});
}
static FlutterBridge getInstance() {
return _instance;
}
register(String method, Function(MethodCall) callBack) {
_listeners[method] = callBack;
}
unRegister(String method) {
_listeners.remove(method);
}
MethodChannel bridge() {
return _bridge;
}
}
flutter端调用:
class _MyAppState extends State<MyApp> {
void initState() {
super.initState();
print('------flutter端------初始化');
///注册监听,接受android端调用的update方法,并返回给android
///注意:我们在BaseApplication初始化FlutterEngine的时候,会走到这里,所以即使没有启动flutter页面,也能收到下边的回调。
FlutterBridge.getInstance().register("update", (MethodCall call) {
print('------flutter端------value=${call.arguments}');
return Future.value('Flutter收到了,返回');
});
}
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(title: const Text('flutter和native间通信')),
body: Center(
child:GestureDetector(
child: const Text('发送数据到android'),
onTap: (){
///向android端发送一个方法为send的数据
FlutterBridge.getInstance().bridge().invokeMethod("send","发送给android");
},
) ,
),
),
);
}
}
2,EventChannel的实现
在flutter端注册监听代码如下:
static const EventChannel _eventChannel = EventChannel("EventChannel");
void initState() {
super.initState();
print('------flutter端------初始化');
_eventChannel.receiveBroadcastStream().listen((event) {
print('------flutter端 EventChannel------value=$event');
});
}
在android端发送数据代码如下:
eventSink: EventSink? = null
// 初始化EventChannel事件
val eventChannel =
EventChannel(flutterEngine.dartExecutor.binaryMessenger, "EventChannel")
eventChannel.setStreamHandler(object : EventChannel.StreamHandler {
override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
instance!!.apply {
eventSink = events;
}
Log.e(javaClass.simpleName, "onListen: arguments=${arguments}")
}
override fun onCancel(arguments: Any?) {
instance!!.apply {
eventSink = null;
}
Log.e(javaClass.simpleName, "onCancel")
}
})
//发送数据
val arr1 = mutableListOf<Int>(1,2,3)
eventSink?.success(arr1)
3,BaseMessageChannel的实现
flutter端注册监听如下:
class _MyAppState extends State<MyApp> {
static const _messageChannel =
BasicMessageChannel("BasicMessageChannel", StandardMessageCodec());
void initState() {
super.initState();
print('------flutter端------初始化');
_messageChannel.setMessageHandler((message) async {
print('------flutter端 BasicMessageChannel------value=$message');
return '返回给android';
});
}
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(title: const Text('flutter和native间通信')),
body: Center(
child: GestureDetector(
child: const Text('发送数据到android'),
onTap: () async {
var result =
await _messageChannel.send({'name': 'Jackson', 'age': 18});
},
),
),
),
);
}
}
android端代码如下:
private lateinit var messageChannel: BasicMessageChannel<Any>
//初始化 BasicMessageChannel
instance!!.apply {
messageChannel = BasicMessageChannel(
flutterEngine.dartExecutor.binaryMessenger,
"BasicMessageChannel",
StandardMessageCodec()
)
messageChannel.setMessageHandler(object : MessageHandler<Any> {
override fun onMessage(message: Any?, reply: BasicMessageChannel.Reply<Any>) {
Log.e(javaClass.simpleName, "onMessage: message=${message}")
}
})
}
//发送数据
val arr1 = mutableListOf("Message1", "Message2")
messageChannel.send(arr1)
android端代码
import android.util.Log
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.*
import io.flutter.plugin.common.BasicMessageChannel.MessageHandler
import io.flutter.plugin.common.EventChannel.EventSink
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
/**
* Flutter和Native通信插件
*/
open class FlutterBridge {
private var eventSink: EventSink? = null
private lateinit var methodChannel: MethodChannel
private lateinit var basicMessageChannel: BasicMessageChannel<Any>
companion object {
@JvmStatic
var instance: FlutterBridge? = null
private set
@JvmStatic
fun init(flutterEngine: FlutterEngine): FlutterBridge? {
//初始化MethodChannel事件
instance!!.apply {
val methodChannel = MethodChannel(
flutterEngine.dartExecutor,
"MethodChannel"
)
if (instance == null) {
FlutterBridge().also { instance = it }
}
methodChannel.setMethodCallHandler(object : MethodCallHandler {
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
Log.e(
javaClass.simpleName,
"onMethodCall: methodName=" + call.method + ",name=" + call.arguments
)
}
})
}
// 初始化EventChannel事件
val eventChannel =
EventChannel(flutterEngine.dartExecutor.binaryMessenger, "EventChannel")
eventChannel.setStreamHandler(object : EventChannel.StreamHandler {
override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
instance!!.apply {
eventSink = events;
}
Log.e(javaClass.simpleName, "onListen: arguments=${arguments}")
}
override fun onCancel(arguments: Any?) {
instance!!.apply {
eventSink = null;
}
Log.e(javaClass.simpleName, "onCancel")
}
})
//初始化 BasicMessageChannel
instance!!.apply {
basicMessageChannel = BasicMessageChannel(
flutterEngine.dartExecutor.binaryMessenger,
"BasicMessageChannel",
StandardMessageCodec()
)
basicMessageChannel.setMessageHandler(object : MessageHandler<Any> {
override fun onMessage(message: Any?, reply: BasicMessageChannel.Reply<Any>) {
Log.e(javaClass.simpleName, "onMessage: message=${message}")
}
})
}
return instance
}
}
/**
* 发送MethodChannel数据
*/
fun sendMethod(methodType: String, callback: MethodChannel.Result) {
val arr1 = mutableListOf("MethodChannel1", "MethodChannel2")
methodChannel.invokeMethod(methodType, arr1, callback)
}
/**
* 发送EventChannel数据
*/
fun sendEvent() {
val arr1 = mutableListOf("EventChannel1", "EventChannel2")
eventSink?.success(arr1)
}
/**
* 发送BasicMessageChannel数据
*/
fun sendMessage() {
val arr1 = mutableListOf("Message1", "Message2")
basicMessageChannel.send(arr1)
}
}
package com.example.flutter_demo
import FlutterBridge
import android.annotation.SuppressLint
import android.os.Bundle
import android.util.Log
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import io.flutter.embedding.android.FlutterActivity
import io.flutter.plugin.common.MethodChannel
class MainActivity : AppCompatActivity() {
@SuppressLint("MissingInflatedId")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<Button>(R.id.btn).setOnClickListener {
startActivity(
//启动flutter页面
FlutterActivity.withCachedEngine("engine_id").build(this)
)
}
findViewById<Button>(R.id.send).setOnClickListener {
//发送MethodChannel数据 有回调
FlutterBridge.instance?.sendMethod("update", object : MethodChannel.Result {
override fun success(result: Any?) {
Log.e(javaClass.simpleName, "MethodChannel success=" + result.toString())
}
override fun error(errorCode: String, errorMessage: String?, errorDetails: Any?) {
Log.e(javaClass.simpleName, "MethodChannel error")
}
override fun notImplemented() {
Log.e(javaClass.simpleName, "MethodChannel notImplemented")
}
})
}
findViewById<Button>(R.id.send).setOnClickListener {
//发送EventChannel数据
FlutterBridge.instance?.sendEvent()
}
findViewById<Button>(R.id.send).setOnClickListener {
//发送EventChannel数据
FlutterBridge.instance?.sendMessage()
}
}
}
flutter端代码:
import 'package:flutter/services.dart';
///Flutter通信框架
class FlutterBridge {
static final FlutterBridge _instance = FlutterBridge._();
final MethodChannel _methodChannel = const MethodChannel('MethodChannel');
static const _eventChannel = EventChannel("EventChannel");
static const _basicMessageChannel =
BasicMessageChannel("BasicMessageChannel", StandardMessageCodec());
FlutterBridge._() {
_methodChannel.setMethodCallHandler((MethodCall call) {
print('------flutter端 MethodChannel------value=${call.arguments}');
return Future.value("MethodChannel");
});
_eventChannel.receiveBroadcastStream().listen((event) {
print('------flutter端 EventChannel------value=$event');
});
_basicMessageChannel.setMessageHandler((message) async {
print('------flutter端 BasicMessageChannel------value=$message');
return '返回给android';
});
}
static FlutterBridge getInstance() {
return _instance;
}
///发送MethodChannel数据
void sendMethodChannel(type) {
_methodChannel
.invokeListMethod(type, {'key': 'MethodChannel', 'value': 18});
}
///发送BasicMessageChannel数据
void sendBasicMessageChannel() {
_basicMessageChannel.send({'key': 'BasicMessageChannel', 'value': 18});
}
}