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
相关产品推荐
相关产品推荐

