Flutter 混合开发 (三):Android 与 Flutter 之间通信详细指南
Future<T> send(T?message)
参数 message 为要传递的参数。Future 为发送消息后等待 Native 回复的回调函数。
BasicMessageChannel 实战:Android 端和 Flutter 端相互发送消息,并且在收到消息后返回对方信息
Android 端代码:
//初始化 BasicMessageChannel
BasicMessageChannel<String> basicMessageChannel = new BasicMessageChannel<>(flutterView,
"BasicMessageChannelPlugin",StringCodec.INSTANCE);
//接受消息
basicMessageChannel.setMessageHandler((message, reply) -> {
mTvDart.setText(message);
reply.reply("收到 dart 数据:接受成功");
});
//发送消息
basicMessageChannel.send(message, reply -> mTvDart.setText(reply));
Dart 端代码:
//初始化 BasicMessageChannel
static const BasicMessageChannel<String> _basicMessageChannel =
BasicMessageChannel("BasicMessageChannelPlugin", StringCodec());
// 接受消息
void handleBasicMessageChannel() {
_basicMessageChannel
.setMessageHandler((String message) => Future<String>(() {
setState(() {
showMessage = message;
});
return "收到 Native 的消息:接受成功";
}));
}
//发送消息
response = await _basicMessageChannel.send(_controller.text);
setState(() {
showMessage = response;
});
最后效果为下图,红色分割线上部分为 Native 页面,下部分为 Flutter 页面。
================================================================================
使用 MethodChannel 相关方法的参数类型及含义和 BasicMessageChannel 的参数含义都是相同的,下面就不一一解释了。
Androd 端相关方法:
MethodChannel(BinaryMessenger messenger, String name)
MethodChannel(BinaryMessenger messenger, String name, MethodCodec codec)
第一个构造函数会构造一个 StandardMethodCodec.INSTANCE 类型的 MethodCodec。MethodCodec 定义了两种类型:JSONMethodCodec 和 StandardMethodCodec。
如果想接受来自 Dart 端的消息则使用:
setMethodCallHandler(@Nullable?MethodChannel.MethodCallHandler handler)
MethodCallHandler 为接口,回调方法为:
public interface MethodCallHandler {
void onMethodCall(MethodCall call, MethodChannel.Result result);
}
call 参数有两个成员变量,String 类型的 call.method 表示调用的方法名,Object 类型的 call.arguments 表示调用方法所传递的入参。result 是回复此消息的回调函数提供了 result.success,result.error,result.notImplemented 方法调用。
发送消息主动调用 Dart 代码则使用 invokeMethod 方法
invokeMethod(@NonNull String method, @Nullable Object arguments)
invokeMethod(String method, @Nullable Object arguments, Result callback)
第二个方法多了一个 callback,它是用来接受 Dart 端收到消息后的回复信息。
public interface Result {
void success(@Nullable Object result);
void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails);
void notImplemented();
}
Dart 端相关方法:
const?MethodChannel(this.name, [this.codec =?const?StandardMethodCodec()])
构造函数默认是使用 StandardMethodCodec 编解码器。
通过 setMethodCallHandler 方法接受来自 Native 的方法调用,通过 invokeMethod 方法调用 Native 端的方法。
void setMethodCallHandler(Future<dynamic>?handler(MethodCall?call))
Future<T> invokeMethod<T>(String?method, [?dynamic?arguments?])
MethodChannel 实战: Native 端调用 Dart 端的 getPlatform 方法返回当前的 os 平台,Dart 端调用 Native 端的 getBatteryLevel 方法获取当前手机电量。
Android 端代码:
//初始化 MethodChannel
MethodChannel methodChannel = new MethodChannel(flutterView, "MethodChannelPlugin");
mBtnTitle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//调用 dart 端 getPlatform 方法
methodChannel.invokeMethod("getPlatform", null, new MethodChannel.Result() {
@Override
public void success(@Nullable Object result) {
mTvDart.setText(result.toString());
}
@Override
public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) {
mTvDart.setText(errorCode + "==" + errorMessage);
}
@Override
public void notImplemented() {
mTvDart.setText("未实现 getPlatform 方法");
}
});
}
});
//接受 dart 的调用
methodChannel.setMethodCallHandler((call, result) -> {
switch (call.method) {
case "getBatteryLevel":
int batteryLevel = getBatteryLevel();
if (batteryLevel != -1) {
result.success("电量为:" + batteryLevel);
} else {
result.error("1001", "调用错误", null);
}
break;
default:
result.notImplemented();
break;
}
});
Dart 端代码:
// receive
void handleMethodChannelReceive() {
Future<dynamic> platformCallHandler(M
ethodCall call) async {
switch (call.method) {
case "getPlatform":
return getPlatformName(); //调用 success 方法
// return PlatformException(code: '1002',message: "出现异常"); //调用 error
break;
}
}
_methodChannel.setMethodCallHandler(platformCallHandler);
// _methodChannel.setMethodCallHandler(null); //调用 notImplemented
}
//send
void handleMethodChannelSend() async {
try {
response = await _methodChannel.invokeMethod("getBatteryLevel");
print(response);
setState(() {
showMessage = response;
});
} catch (e) {
//捕获 error 和 notImplemented 异常
setState(() {
showMessage = e.message;
});
}
}
当我们在使用 setMethodCallHandler 接受到 native 的消息时,直接调用相关方法即可调用 Native 端的 success 回调。
如果直接抛异常如 PlatformException,那么就调用 Native 端的 error 回调。
PlatformException(code:?'1002',message:?"出现异常")
如果我们直接设置 handler 为 null
_methodChannel.setMethodCallHandler(null);
那么就会调用 Native 端的 notImplemented 方法回调。
同理我们在 Dart 端使用 invokeMethod 方法是,需要进行异常捕获以便于我们接受到 Native 端调用的 error 和 notImplemented 方法回调。
最后效果为下图,红色分割线上部分为 Native 页面,下部分为 Flutter 页面。
===============================================================================
EventChannel 内部实现原理其实也是通过 MethodChannel 来完成的。
Android 端相关代码:
EventChannel(BinaryMessenger messenger, String name)
EventChannel(BinaryMessenger messenger, String name, MethodCodec codec)
同样的,也是两个构造,默认 codec 为 StandardMethodCodec,EventChannel 和 MethodChannel 的 codec 都属于 MethodCodec 范畴。
通过 setStreamHandler 来监听 Dart 端发送的消息,
void?setStreamHandler(EventChannel.StreamHandler?handler)
其中 handler 是一个接口:
public interface StreamHandler {
void onListen(Object args, EventChannel.EventSink eventSink);
void onCancel(Object o);
}
评论