Flutter isolate_handler派生隔离区调用平台通道报MissingPluginException
问题原因
MissingPluginException 触发的根本原因:Flutter 框架默认只会给主Isolate绑定平台通道(MethodChannel)对应的二进制消息信使(BinaryMessenger),自定义派生的Isolate没有和Flutter引擎的原生消息路由做关联,引擎找不到对应通道的处理逻辑,就会抛出该异常。
isolate_handler 包只封装了Isolate之间的通信逻辑,不会自动给派生Isolate注册平台通道桥接,在派生Isolate里直接创建MethodChannel发请求,消息根本到不了Android端注册的MethodCallHandler,自然会报找不到插件的错误。主Isolate调用时没有这个问题,就是因为主Isolate默认已经和引擎的消息路由完成了绑定。
修复方案
不要在派生Isolate里直接调用MethodChannel,通过Isolate间通信把平台调用请求转发到主Isolate执行,再把结果回传给派生Isolate即可,具体修改步骤:
- 修改TestingIsolate代码,拆分平台调用逻辑到主Isolate
import 'dart:async'; import 'package:flutter/services.dart'; import 'package:isolate_handler/isolate_handler.dart'; class TestingIsolate { static int _callCount = 0; static int _lastNumber = 0; final _isolates = IsolateHandler(); final resultStreamController = StreamController<double>(); static const platform = MethodChannel('com.mycompany.plugin_performance_test_poc'); static void _entryPoint(Map<String, dynamic> context) { final messenger = HandledIsolate.initialize(context); // 监听主Isolate回传的平台调用结果 messenger.listen((message) { if (message['type'] == 'platform_result') { _lastNumber = message['data']; _callCount++; } }); _startTesting(messenger); } Stream<double> init() { _isolates.spawn<double>(_entryPoint, onReceive: (message) async { // 主Isolate收到派生Isolate的平台调用请求,直接执行通道调用 if (message['type'] == 'invoke_platform') { final res = await platform.invokeMethod('performanceTest', {'data': message['data']}); // 调用结果回传给派生Isolate _isolates.send({ 'type': 'platform_result', 'data': res }); } // 收到最终测试结果,推送给UI层 if (message['type'] == 'final_result') { resultStreamController.add(message['data']); } }); return resultStreamController.stream; } static void _startTesting(HandledIsolateMessenger messenger) { final stopwatch = Stopwatch(); stopwatch.start(); while (stopwatch.elapsedMilliseconds < 3000) { // 向主Isolate发送平台调用请求,不直接在当前Isolate调用MethodChannel messenger.send({ 'type': 'invoke_platform', 'data': _lastNumber }); // 释放事件循环,避免微任务队列阻塞导致回调无法执行 await Future.delayed(Duration.zero); } stopwatch.stop(); // 计算QPS结果发送回主Isolate messenger.send({ 'type': 'final_result', 'data': _callCount * 3000 / stopwatch.elapsedMilliseconds }); } }
- 原有代码的额外问题修复
- 之前的while循环没有插入空等待,会直接阻塞Isolate事件队列,
invokeMethod的then回调永远没有执行机会,计数会始终为0 - 现有统计逻辑在3秒循环结束后就直接计算QPS,此时队列中还有未返回的平台请求,统计结果会偏低,如果要拿到准确数值,可以加计数器记录在途请求数,等所有请求返回后再计算最终结果
- 之前的while循环没有插入空等待,会直接阻塞Isolate事件队列,
- Android端原生代码不需要做任何调整,保持原有实现即可。
内容的提问来源于stack exchange,提问作者Dusan Milosevic
相关产品推荐
相关产品推荐

