You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter MethodChannel如何同时调用?仅触发methodB问题排查

问题:Flutter与iOS原生MethodChannel异步调用仅收到一个回调

我使用MethodChannel实现Flutter与iOS原生通信,编写了methodA和methodB两个原生方法,均通过DispatchQueue延迟1秒后调用invokeMethod触发Flutter端对应方法。同时调用这两个方法后,Flutter端仅收到methodB的调用,疑惑异步调用为何出现此问题,寻求解决办法。

原生代码

private func methodA() {
        DispatchQueue.main.asyncAfter(deadline: .now()+1) { [weak self] in
            self?.channel?.invokeMethod("methodA", arguments: nil) { result in
            }
        }
}
private func methodB() {
        DispatchQueue.main.asyncAfter(deadline: .now()+1) { [weak self] in
            self?.channel?.invokeMethod("methodB", arguments: nil) { result in
            }
        }
}

原生调用方式

methodA()
methodB()

Flutter端代码

//main.dart
channel.setMethodCallHandler((MethodCall call) async {
    if (call.method == 'methodA') {
      debugPrint("methodA------");
      final items = await dbHelper.items();
      return json.encode(items);
    } else if (call.method == 'methodB') {
      debugPrint("methodB------");
      final list = await dbHelper.list();
      return json.encode(list);
    }
  });

  runApp(MyApp());

问题原因

核心原因是MethodChannel的原生端调用是串行处理机制:当你几乎同时触发两个invokeMethod调用时,第二个调用会被阻塞,直到第一个调用的Flutter端处理完成并返回结果。而你的Flutter端handler中处理methodA时,await dbHelper.items()是一个异步耗时操作,导致methodA的回调迟迟无法完成,直接阻塞了methodB的调用传递。

解决办法

办法一:Flutter端handler快速返回,耗时操作后台执行

修改Flutter端的方法处理器,不在handler的异步函数中直接等待耗时操作,而是启动独立的异步任务处理业务逻辑,立刻返回结果(原生端未处理result,可返回null):

channel.setMethodCallHandler((MethodCall call) async {
  if (call.method == 'methodA') {
    debugPrint("methodA------");
    // 启动独立异步任务处理耗时操作,不阻塞handler返回
    Future(() async {
      final items = await dbHelper.items();
      // 后续业务逻辑可在这里处理
    });
    return null;
  } else if (call.method == 'methodB') {
    debugPrint("methodB------");
    Future(() async {
      final list = await dbHelper.list();
      // 后续业务逻辑可在这里处理
    });
    return null;
  }
  return null;
});

办法二:原生端使用独立MethodChannel

给两个方法分别创建独立的MethodChannel,让它们的调用互不干扰:

// 定义两个独立的Channel
private let channelA = FlutterMethodChannel(name: "com.example.channelA", binaryMessenger: flutterViewController.binaryMessenger)
private let channelB = FlutterMethodChannel(name: "com.example.channelB", binaryMessenger: flutterViewController.binaryMessenger)

private func methodA() {
    DispatchQueue.main.asyncAfter(deadline: .now()+1) { [weak self] in
        self?.channelA.invokeMethod("methodA", arguments: nil) { result in
        }
    }
}

private func methodB() {
    DispatchQueue.main.asyncAfter(deadline: .now()+1) { [weak self] in
        self?.channelB.invokeMethod("methodB", arguments: nil) { result in
        }
    }
}

Flutter端也对应注册两个Channel的handler:

final channelA = MethodChannel('com.example.channelA');
final channelB = MethodChannel('com.example.channelB');

channelA.setMethodCallHandler((call) async {
  debugPrint("methodA------");
  final items = await dbHelper.items();
  return json.encode(items);
});

channelB.setMethodCallHandler((call) async {
  debugPrint("methodB------");
  final list = await dbHelper.list();
  return json.encode(list);
});

内容的提问来源于stack exchange,提问作者magic_9527

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 18:32:53