【解决Flutter 、Native通信,回调结果错乱问题】

  • 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端发送消息:(略,注册消息和发送消息跟上面是反过来的,但是异步需要注意的地方是一样的)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值