- Flutter主动向Native端发送消息;
Flutter端, 发送消息:
class AlarmMethodChannel {
static final MethodChannel _channel = MethodChannel('hcc_alarmpage_method_channel');
static final AlarmMethodChannel _alarmMethodChannel = AlarmMethodChannel._interval();
// 单例
factory AlarmMethodChannel() {
return _alarmMethodChannel;
}
// 向原生发送下载图片消息
Future downloadImage(Map param)async {
var response = await _channel.invokeMethod('downloadImage', param);
// 图片流转成Image
if(response != null) {
Image image = Image.memory(response, fit: BoxFit.fill,);
return image;
}
// 没有数据,返回空字符
return '';
}
}
OC端,注册消息:
FlutterMethodChannel *methodChannel = [FlutterMethodChannel methodChannelWithName:@"hcc_alarmpage_method_channel" binaryMessenger:viewController.binaryMessenger];
__weak typeof(self) weakSelf = self;
[methodChannel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
__strong typeof(weakSelf) self = weakSelf;
[self handleMethodCall:call result:result];
}];
// 接收消息
- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
NSString *method = call.method;
NSDictionary *arguments = call.arguments;
```
if ([method isEqualToString:@"downloadImage"]) {
[[[PowerImageNetworkImageLoader shareInstance] downloadImageWithArguments:arguments] subscribeNext:^(id x) {
// NSData 结果回调给Flutter
if (x != nil) {
// 下载完成,返回图片流给Flutter, x == 图片二进制流
result(x);
}
}];
}
}
可能存在的严重问题:
Flutter如果同时向原生发送多条下载图片消息,原生由于是异步下载图片,有可能造成,第二张图片先下载完成,原生把下载结果返回给flutter的时候,因为所有的下载消息用的MethodChannel名称是一样的,所以,这时候 flutter不会区分原生到底返回的是哪个图片结果,它只会按照顺序把结果先返回给第一个消息,这样,flutter得到的原生返回结果就是错的。
解决方法 :
动态注册方法,保证方法名唯一
Flutter端,发送消息:
class AlarmMethodChannel {
static final MethodChannel _channel = MethodChannel('hcc_alarmpage_method_channel');
static final AlarmMethodChannel _alarmMethodChannel = AlarmMethodChannel._interval();
// 单例
factory AlarmMethodChannel() {
return _alarmMethodChannel;
}
// 向原生发送下载图片消息
Future downloadImage(Map param)async {
// 重点 -------------------------------- 方法名 + 消息ID
var response = await _channel.invokeMethod('downloadImage' + param['guid'], param);
// 图片流转成Image
if(response != null) {
Image image = Image.memory(response, fit: BoxFit.fill,);
return image;
}
// 没有数据,返回空字符
return '';
}
}
OC端,注册消息:
FlutterMethodChannel *methodChannel = [FlutterMethodChannel methodChannelWithName:@"hcc_alarmpage_method_channel" binaryMessenger:viewController.binaryMessenger];
__weak typeof(self) weakSelf = self;
[methodChannel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
__strong typeof(weakSelf) self = weakSelf;
[self handleMethodCall:call result:result];
}];
// 接收消息
- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
NSString *method = call.method;
NSDictionary *arguments = call.arguments;
```
// 重点 -------------------------------- 方法名 + 消息ID
if ([method isEqualToString:[NSString stringWithFormat:@"downloadImage%@", arguments[@"guid"]]]) {
[[[PowerImageNetworkImageLoader shareInstance] downloadImageWithArguments:arguments] subscribeNext:^(id x) {
// NSData 结果回调给Flutter
if (x != nil) {
// 下载完成,返回图片流给Flutter, x == 图片二进制流
result(x);
}
}];
}
}
重点:方法名 + ID,保证方法唯一
总结:Flutter如果同时需要原生支持多个异步任务,两端通信的时候,方法名称一定要保证唯一性,避免 因为异步导致原生回调结果错乱问题
- Native主动向Flutter端发送消息:(略,注册消息和发送消息跟上面是反过来的,但是异步需要注意的地方是一样的)