Flutter 与 Android/iOS 之间信息交互通过 Platform Channel 进行桥接; Flutter 定义了三种不同的 Channel;但无论是传递方法还是传递事件,其本质上都是数据的传递;
- MethodChannel:用于传递方法调用;
- EventChannel:用于数据流信息通信;
- BasicMessageChannel:用于传递字符串和半结构化的信息;
每种 Channel 均包含三个成员变量;
- name:代表 Channe 唯一标识符,Channel 可以包含多个,但 name 为唯一的;
- messager:代表消息发送与接收的工具 BinaryMessenger;
- codec:代表消息的编解码器
1、MethodChannel:
flutter代码:
// 调用原生方法
static const methodChannel = const MethodChannel('flutter_and_native_101');
static Future<dynamic> invokNative(String method, {Map arguments}) async {
if (arguments == null) {
return await methodChannel.invokeMethod(method);
} else {
return await methodChannel.invokeMethod(method, arguments);
}
}
// 监听原生返回
Future<dynamic> nativeMessageListener() async {
methodChannel.setMethodCallHandler((resultCall) {
MethodCall call = resultCall;
String method = call.method;
Map arguments = call.arguments;
int code = arguments["code"];
String message = arguments["message"];
setState(() {
recive += " code $code message $message and method $method \n";
print(recive);
});
return null;
});
}
// 调用
onPressed: () {
invokNative("test")
..then((result) {
int code = result["code"];
String message = result["message"];
setState(() {
recive = "invokNative 中的回调 code $code message $message ";
});
});
}
android代码:
private void methodChannelFunction() {
mMethodChannel = new MethodChannel(getFlutterView(), "flutter_and_native_101");
//设置监听
mMethodChannel.setMethodCallHandler(
new MethodChannel.MethodCallHandler() {
@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
String lMethod = call.method;
if (lMethod.equals("test")) {
Toast.makeText(mContext, "flutter 调用到了 android test", Toast.LENGTH_SHORT).show();
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("message", "result.success 返回给flutter的数据");
resultMap.put("code", 300);
result.success(resultMap);
} else if (lMethod.equals("test2")) {
//Toast.makeText(mContext, "flutter 调用到了 android test", Toast.LENGTH_SHORT).show();
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("message", "android 主动调用 flutter test 方法");
resultMap.put("code", 301);
mMethodChannel.invokeMethod("test", resultMap);
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
Map<String, Object> resultMap2 = new HashMap<>();
resultMap2.put("message", "android 主动调用 flutter test 方法 delay 2000ms");
resultMap2.put("code", 302);
mMethodChannel.invokeMethod("test2", resultMap2);
}
}, 2000);
} else if (lMethod.equals("test3")) {
//测试通过Flutter打开Android Activity
Toast.makeText(mContext, "flutter 调用到了 android test3", Toast.LENGTH_SHORT).show();
Intent lIntent = new Intent(MainActivity.this, TestMethodChannelActivity.class);
MainActivity.this.startActivity(lIntent);
} else {
result.notImplemented();
}
}
}
);
}
通过 flutter_and_native_101 唯一标识将flutter和andorid之间的 channel 连接起来。flutter 传递对应的方法名称在native 接受方法后解析名称,在对比调用不同逻辑。
2、EventChannel:相当于接收来自native的通知
只能是原生发送消息给Flutter端,例如监听手机电量变化,网络变化,传感器等。
flutter 端:
//EventChannel( 用于数据流(event streams)的通信)
static const EventChannel _eventChannel = const EventChannel('flutter_and_native_102');
Future<dynamic> nativeMessageListener() async {
_eventChannel.receiveBroadcastStream().listen((arguments) {
int code = arguments["code"];
String message = arguments["message"];
setState(() {
recive +=
" code $code message $message \n";
print(recive);
});
}, one rror: (event) {
print(event);
});
}
android原生:
/**
* 此方法适用于android 系统有通知通知到flutter的场景
*
* */
private void eventChannelFunction() {
EventChannel lEventChannel = new EventChannel(getFlutterView(), "flutter_and_native_102");
lEventChannel.setStreamHandler(
new EventChannel.StreamHandler() {
@Override
public void onListen(Object o, EventChannel.EventSink eventSink) {
mEventSink = eventSink;
Log.d("zxzx","event sink = " + o);
mHandler.post(new Runnable() {
@Override
public void run() {
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("message", "注册成功");
resultMap.put("code", 400);
eventSink.success(resultMap);
}
});
}
@Override
public void onCancel(Object o) {
}
}
);
}
同理,flutter注册监听,监听 flutter_and_native_102 channel来的广播。
3、BasicMessageChannel :
它是可以双端通信的,flutter端可以给Android发送消息,Android也可以给Flutter发送消息。
flutter 端:
static const messageChannel = const BasicMessageChannel( 'flutter_and_native_100', StandardMessageCodec());
//发送消息
Future<Map> sendMessage(Map json) async {
Map reply = await messageChannel.send(json);
//解析 原生发给 Flutter 的参数
int code = reply["code"];
String message = reply["message"];
setState(() {
recive = "code:$code message:$message";
});
return reply;
}
//接收消息监听
void receiveMessage() {
messageChannel.setMessageHandler((result) async {
//解析 原生发给 Flutter 的参数
int code = result["code"];
String message = result["message"];
setState(() {
recive = "receiveMessage: code:$code message:$message";
});
return 'Flutter 已收到消息';
});
}
android端:
private void messageChannelFunction() {
//消息接收监听
//BasicMessageChannel (主要是传递字符串和一些半结构体的数据)
mMessageChannel = new BasicMessageChannel<Object>(getFlutterView(), "flutter_and_native_100", StandardMessageCodec.INSTANCE);
// 接收消息监听
mMessageChannel.setMessageHandler(new BasicMessageChannel.MessageHandler<Object>() {
@Override
public void onMessage(Object o, BasicMessageChannel.Reply<Object> reply) {
System.out.println("onMessage: " + o.toString());
Map lJSONObject = null;
//解析Flutter 传递的参数
lJSONObject = (HashMap) o;
//方法名标识
Object lMethod = lJSONObject.get("method");
Log.d("MainActivity","lmethod = " + lMethod);
//测试 reply.reply()方法 发消息给Flutter
if (lMethod.equals("test")) {
Toast.makeText(mContext, "flutter 调用到了 android test", Toast.LENGTH_SHORT).show();
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("message", "reply.reply 返回给flutter的数据");
resultMap.put("code", 200);
reply.reply(resultMap);
} else if (lMethod.equals("test2")) {
//测试 mMessageChannel.send 发消息给Flutter
channelSendMessage();
} else if (lMethod.equals("test3")) {
//测试通过Flutter打开Android Activity
Toast.makeText(mContext, "flutter 调用到了 android test3", Toast.LENGTH_SHORT).show();
Intent lIntent = new Intent(MainActivity.this, TestBasicMessageActivity.class);
MainActivity.this.startActivity(lIntent);
}
}
});
}
private void channelSendMessage() {
Toast.makeText(mContext, "flutter 调用到了 android test", Toast.LENGTH_SHORT).show();
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("message", "message Channel.reply 返回给flutter的数据");
resultMap.put("code", 201);
mMessageChannel.send(resultMap, new BasicMessageChannel.Reply<Object>() {
@Override
public void reply(Object o) {
Log.d("MainActivity", "mMessageChannel send 回调 " + o);
}
});
}
具体的使用哪种通信方式,看具体的使用场景。