Flutter Method Channel(Android原生)调用报MissingPluginException求助
问题描述
编写了Flutter与Android原生的Method Channel交互代码,调用getNativeData方法时触发MissingPluginException,提示找不到该方法实现,调整代码、清理项目后仍未解决。
Android原生代码
package com.testmrthodcn; import androidx.annotation.NonNull; import android.os.Bundle; import android.view.View; import android.widget.Button; import io.flutter.embedding.android.FlutterActivity; import io.flutter.embedding.engine.FlutterEngine; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugins.GeneratedPluginRegistrant; public class MainActivity extends FlutterActivity { public static final String CHANNEL = "com.itcat.humanos/sasigarn"; @Override public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine){ super.configureFlutterEngine(flutterEngine); System.out.println("flutter print :: configureFlutterEngine222"); new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL) .setMethodCallHandler((call, result) -> { System.out.println("flutter print :: result"); if (call.method.equals("getNativeData")) { System.out.println("flutter print :: if configureFlutterEngine"); String data = "55555555 from native"; result.success(data); } else { System.out.println("flutter print :: else configureFlutterEngine"); result.notImplemented(); } } ); System.out.println("flutter print :: after MethodChannel"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); GeneratedPluginRegistrant.registerWith(this.getFlutterEngine()); setContentView(R.layout.activity_main); Button button = findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity( FlutterActivity .withNewEngine() .initialRoute("/test_methodchannel") .build(MainActivity.this) ); } }); }
Flutter端代码
import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class TestMethodchannel extends StatefulWidget { @override _TestMethodchannel createState() => _TestMethodchannel(); } class _TestMethodchannel extends State<TestMethodchannel> { static const channel = const MethodChannel('com.itcat.humanos/sasigarn'); String _dataFromNative = 'No Data'; Future<void> _getNativeData() async { String? data; try { final String? result = await channel.invokeMethod<String>('getNativeData', {'arg1': 'value1', 'arg2': 'value2'}); data = result; } on PlatformException catch (e) { data = "Failed to get data: '${e.message}'."; } print('flutter data : '+data.toString()); setState(() { _dataFromNative = data.toString(); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Native Data Fetcher'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ ElevatedButton( onPressed: _getNativeData, child: Text('Fetch Data from Native'), ), SizedBox(height: 20), Text('Data from Native: $_dataFromNative'), ], ), ), ); } }
错误信息
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: MissingPluginException(No implementation found for method getNativeData on channel com.itcat.humanos/sasigarn)
#0 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:308:7)
问题根源与解决方法
核心问题
你在MainActivity中配置了MethodChannel,但点击按钮启动的是全新的FlutterEngine实例(通过FlutterActivity.withNewEngine()创建),这个新引擎并没有注册MethodChannel的处理逻辑,导致调用时找不到实现。
解决步骤
方案一:复用现有FlutterEngine(推荐)
修改按钮点击事件,复用当前Activity的FlutterEngine,而非创建新引擎:
button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity( FlutterActivity .withCachedEngine() .initialRoute("/test_methodchannel") .build(MainActivity.this) ); } });
同时在MainActivity的configureFlutterEngine方法中,给引擎设置唯一ID以支持缓存复用:
@Override public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine){ super.configureFlutterEngine(flutterEngine); // 设置引擎ID,用于缓存复用 flutterEngine.getNavigationChannel().setInitialRoute("/"); // 保留原有MethodChannel注册逻辑 new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL) .setMethodCallHandler((call, result) -> { // ...原有逻辑不变... }); }
方案二:为新引擎注册MethodChannel
若必须使用新引擎,需自定义FlutterActivity并注册MethodChannel:
- 创建自定义FlutterActivity类:
public class CustomFlutterActivity extends FlutterActivity { public static final String CHANNEL = "com.itcat.humanos/sasigarn"; @Override public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { super.configureFlutterEngine(flutterEngine); // 注册MethodChannel new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL) .setMethodCallHandler((call, result) -> { if (call.method.equals("getNativeData")) { String data = "55555555 from native"; result.success(data); } else { result.notImplemented(); } }); } }
- 修改按钮点击事件,启动自定义FlutterActivity:
button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, CustomFlutterActivity.class); intent.putExtra("route", "/test_methodchannel"); startActivity(intent); } });
额外检查项
- 确保两端Channel名称完全一致(
com.itcat.humanos/sasigarn),大小写、符号均不能出错 - 执行
flutter clean后重新编译项目,清除缓存 - 确认Android端代码已正确同步到设备,无编译错误
内容的提问来源于stack exchange,提问作者Apudsagan Captain

