Flutter调用Android原生组件仅首次生效,后续报MissingPluginException
解决Flutter调用原生Activity首次正常、后续报MissingPluginException的问题
核心问题分析
出现这个问题的关键原因有两个:
- MethodChannel调用未返回结果:代码里注释了
result.success()和result.notImplemented(),导致MethodChannel的调用会话一直处于挂起状态,后续再调用时通道无法正常响应。 - FlutterEngine缓存与通道绑定的生命周期不匹配:缓存的FlutterEngine从原生Activity返回后,可能出现通道绑定失效的情况。
具体解决步骤
1. 修复MethodCall的结果返回(优先处理)
Android端的MethodCallHandler里,必须保证每个方法调用都调用result的对应方法,否则会破坏通道的正常状态:
new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL) .setMethodCallHandler((call, result) -> { if(call.method.equals("StartSecondActivity")){ Intent intent = new Intent(MainActivity.this, IntentWedgeSample.class); startActivity(intent); // 必须返回结果,告知Flutter调用成功 result.success("ActivityStarted"); }else{ // 未实现的方法要返回notImplemented result.notImplemented(); } });
Dart端建议加上错误捕获,避免未处理异常:
try { String result = await _channel.invokeMethod('StartSecondActivity'); print(result); } on PlatformException catch (e) { print("调用失败: ${e.message}"); }
2. 调整FlutterEngine缓存的生命周期
代码里用了FlutterEngineCache缓存引擎,需要在Activity销毁时清理缓存,避免无效引擎被复用:
在MainActivity里重写cleanUpFlutterEngine方法:
@Override public void cleanUpFlutterEngine(@NonNull FlutterEngine flutterEngine) { super.cleanUpFlutterEngine(flutterEngine); // 移除缓存的引擎 FlutterEngineCache.getInstance().remove("bac_flutter_id"); }
如果确实需要复用引擎,在onCreate里检查缓存是否存在,再决定是否创建新引擎并重新绑定通道:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); FlutterEngine cachedEngine = FlutterEngineCache.getInstance().get("bac_flutter_id"); if (cachedEngine == null) { // 缓存不存在则创建新引擎并缓存 FlutterEngine flutterEngine = new FlutterEngine(this); flutterEngine.getNavigationChannel().setInitialRoute("/waybill"); FlutterEngineCache.getInstance().put("bac_flutter_id", flutterEngine); GeneratedPluginRegistrant.registerWith(flutterEngine); // 注册通道 new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL) .setMethodCallHandler((call, result) -> { if(call.method.equals("StartSecondActivity")){ Intent intent = new Intent(MainActivity.this, IntentWedgeSample.class); startActivity(intent); result.success("ActivityStarted"); }else{ result.notImplemented(); } }); } else { // 复用缓存引擎,重新绑定通道确保可用 new MethodChannel(cachedEngine.getDartExecutor().getBinaryMessenger(), CHANNEL) .setMethodCallHandler((call, result) -> { if(call.method.equals("StartSecondActivity")){ Intent intent = new Intent(MainActivity.this, IntentWedgeSample.class); startActivity(intent); result.success("ActivityStarted"); }else{ result.notImplemented(); } }); } }
3. 移除引擎复用(可选简单方案)
如果不需要复用FlutterEngine,直接删掉FlutterEngineCache相关代码,让每次启动都创建新引擎,确保通道每次都正确注册:
@Override public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { super.configureFlutterEngine(flutterEngine); GeneratedPluginRegistrant.registerWith(flutterEngine); flutterEngine.getNavigationChannel().setInitialRoute("/waybill"); // 删掉FlutterEngineCache的put代码 new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL) .setMethodCallHandler((call, result) -> { if(call.method.equals("StartSecondActivity")){ Intent intent = new Intent(MainActivity.this, IntentWedgeSample.class); startActivity(intent); result.success("ActivityStarted"); }else{ result.notImplemented(); } }); }
内容的提问来源于stack exchange,提问作者Rokudo
相关产品推荐
相关产品推荐

