Flutter:尝试向 FlutterEngine 自动注册插件,但找不到并调用 GeneratedPluginRegistrant
Posted
技术标签:
【中文标题】Flutter:尝试向 FlutterEngine 自动注册插件,但找不到并调用 GeneratedPluginRegistrant【英文标题】:Flutter: Tried to automatically register plugins with FlutterEngine but could not find and invoke the GeneratedPluginRegistrant 【发布时间】:2020-10-30 10:44:20 【问题描述】:运行此命令时出现这些错误
flutter run --flavor development -t lib/config/main_development.dart --verbose-system-logs
错误:
Tried to automatically register plugins with FlutterEngine (io.flutter.embedding.engine.FlutterEngine@b5226bb) but could not find and invoke the GeneratedPluginRegistrant.
E/flutter (28896): [ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: MissingPluginException(No implementation found for method initialize on channel flutter_stetho)
颤振医生输出:
➜ flutter doctor -v
[✓] Flutter (Channel master, 1.20.0-8.0.pre.22, on Mac OS X 10.14.6 18G3020, locale en)
• Flutter version 1.20.0-8.0.pre.22 at /Users/vedantrathore/tools/flutter
• Framework revision 61a04b1551 (11 hours ago), 2020-07-09 15:52:19 +0800
• Engine revision 0ec6f6c3f2
• Dart version 2.9.0 (build 2.9.0-20.0.dev 06cb010247)
[✓] android toolchain - develop for Android devices (Android SDK version 29.0.3)
• Android SDK at /Users/vedantrathore/Library/Android/sdk
• Platform android-29, build-tools 29.0.3
• Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b4-5784211)
• All Android licenses accepted.
[✓] Xcode - develop for ios and macOS (Xcode 11.3.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 11.3.1, Build version 11C504
• CocoaPods version 1.9.1
[✓] Android Studio (version 3.6)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin version 44.0.2
• Dart plugin version 192.7761
• Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b4-5784211)
[✓] VS Code (version 1.46.1)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.12.1
[✓] Connected device (1 available)
• GM1901 (mobile) • 192.168.29.75:5555 • android-arm64 • Android 10 (API 29)
• No issues found!
这是我的 app/build.gradle 文件
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists())
localPropertiesFile.withReader('UTF-8') reader ->
localProperties.load(reader)
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null)
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null)
flutterVersionCode = '1'
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null)
flutterVersionName = '1.0'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android
compileSdkVersion 28
sourceSets
main.java.srcDirs += 'src/main/kotlin'
lintOptions
disable 'InvalidPackage'
defaultConfig
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.habitwave"
minSdkVersion 18
targetSdkVersion 28
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
buildTypes
release
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
minifyEnabled true
useProguard true
debug
minifyEnabled true
useProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
flavorDimensions "flutter-flavours"
productFlavors
development
dimension "flutter-flavours"
versionNameSuffix "-dev"
staging
dimension "flutter-flavours"
versionNameSuffix "-stg"
production
dimension "flutter-flavours"
flutter
source '../..'
dependencies
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.google.firebase:firebase-analytics:17.2.2'
我正在尝试使用 flutter_secure_storage 包,因此我必须将 minSdkVersion 设置为 18 并使用 Proguard 规则来避免 multiDex(因为这需要 minSdkVersion 21)
我尝试过的解决方案:
运行flutter clean
,卸载应用,清除~/.pub-cache
从稳定移动到主频道
编辑:
我通过深入研究解决了这个问题并在 Android Studio 中打开了应用程序,进入了 Flutter 活动的实现并设置了一个断点,它尝试注册插件,然后当我运行应用程序时,我发现错误是FacebookSdk 未初始化。我正在使用 pub.dev/packages/flutter_facebook_login 包并忘记了 android 初始化。可以改进错误处理以适应这些场景
【问题讨论】:
【参考方案1】:今天我遇到了同样的问题。我认为这与此有关: https://flutter.dev/docs/development/packages-and-plugins/plugin-api-migration
(可能只是临时解决方案)
我将注册人回信给我的MainActivity.kt
- 如果您的班级正文为空,它可能会有所帮助
package your.package.name
import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
class MainActivity: FlutterActivity()
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine)
GeneratedPluginRegistrant.registerWith(flutterEngine);
【讨论】:
感谢您的意见。但是我深入研究并在 Android Studio 中打开了该应用程序,进入了 Flutter 活动的实现并设置了一个断点,它尝试注册插件,然后当我运行该应用程序时,我发现错误是 FacebookSdk 不是初始化。我正在使用 pub.dev/packages/flutter_facebook_login 包并忘记了初始化。可以改进错误处理以适应这些情况。 是的,几天前出现了类似的错误,当时我在 ios 中实现了 facebook 登录,然后我想从现有项目创建 android 应用程序,也忘记了初始化。因此,同时为两个平台添加软件包是一个好方法:D。祝你有美好的一天! 非常感谢。 @VedantRathore 我也试图包含 Facebook 插件。因为它说: > 如果您使用 5.15 版或更高版本的 Facebook SDK for Android,则无需为 Chrome 自定义选项卡添加活动或意图过滤器。此功能包含在 SDK 中。我假设没有必要修改 Manifest 文件。这真是令人困惑。完成清单设置后,它又可以工作了! :+1:【参考方案2】:我今天也遇到了同样的问题。对于在为 Flutter 开发 Android 插件时遇到此错误的人,此答案可能会有所帮助。
错误是由于插件初始化时发生的 InvocationTargetException。当使用反射调用的方法抛出错误时,会抛出 InvocationTargetException。除了“尝试自动注册插件......”Flutter警告之外没有任何错误日志,所以我在首先调试Flutter源代码(也由OP完成)和之后的代码时发现了异常。
这是引发异常的 Flutter 源码。 (由 Flutter 1.20.4/channel:stable 提供)
private static void registerPlugins(@NonNull FlutterEngine flutterEngine)
try
Class<?> generatedPluginRegistrant =
Class.forName("io.flutter.plugins.GeneratedPluginRegistrant");
Method registrationMethod =
generatedPluginRegistrant.getDeclaredMethod("registerWith",
FlutterEngine.class);
registrationMethod.invoke(null, flutterEngine);
catch (Exception e)
Log.w(
TAG,
"Tried to automatically register plugins with FlutterEngine ("
+ flutterEngine
+ ") but could not find and invoke the GeneratedPluginRegistrant.");
我已将 cmets 添加到可能导致此错误的方法中。您可以使用 Android Studio 调试您的代码,并找到导致插件初始化失败的错误。
public class MyPlugin implements FlutterPlugin, ActivityAware
private MethodChannel methodChannel;
private CustomMethodHandler methodHandler;
private ActivityPluginBinding mActivityBinding;
private void initChannels(final BinaryMessenger messenger)
methodChannel = new MethodChannel(messenger, Channel.MY_METHOD_CHANNEL);
methodHandler= new CustomMethodHandler(null);
methodChannel.setMethodCallHandler(authMethodHandler);
private void teardownChannels()
methodChannel.setMethodCallHandler(null);
methodChannel = null;
private void setupActivity(Activity activity)
methodChannel.setActivity(activity);
private void teardownActivity()
methodChannel.setActivity(null);
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding)
// Debug here for errors.
initChannels(flutterPluginBinding.getBinaryMessenger());
public static void registerWith(Registrar registrar)
MyPlugin myPlugin = new MyPlugin();
myPlugin.initChannels(registrar.messenger());
myPlugin.setupActivity(registrar.activity());
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding)
teardownChannels();
@Override
public void onAttachedToActivity(@NonNull ActivityPluginBinding binding)
// Debug here for errors.
mActivityBinding = binding;
setupActivity(mActivityBinding.getActivity());
@Override
public void onDetachedFromActivityForConfigChanges()
teardownActivity();
@Override
public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding)
mActivityBinding = binding;
setupActivity(mActivityBinding.getActivity());
@Override
public void onDetachedFromActivity()
teardownActivity();
【讨论】:
【参考方案3】:我已将它用于 Firebase 通知和本地通知
您可以像这样手动注册插件:-
Application.java
package com.example.appname;
import io.flutter.app.FlutterApplication;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
import io.flutter.plugins.GeneratedPluginRegistrant;
import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin;
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService;
import com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin;
public class Application extends FlutterApplication implements PluginRegistrantCallback
@Override
public void onCreate()
super.onCreate();
FlutterFirebaseMessagingService.setPluginRegistrant(this);
@Override
public void registerWith(PluginRegistry registry)
FirebaseCloudMessagingPluginRegistrant.registerWith(registry);
MainActivity.java
package com.example.appname;
import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugins.GeneratedPluginRegistrant;
public class MainActivity extends FlutterActivity
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine)
GeneratedPluginRegistrant.registerWith(flutterEngine);
FirebaseCloudMessagingPluginRegistrant.java
package com.example.appname;
import com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin;
public final class FirebaseCloudMessagingPluginRegistrant
public static void registerWith(PluginRegistry registry)
if (alreadyRegisteredWith(registry))
return;
FirebaseMessagingPlugin.registerWith(registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
FlutterLocalNotificationsPlugin.registerWith(registry.registrarFor("com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin"));
private static boolean alreadyRegisteredWith(PluginRegistry registry)
final String key = FirebaseCloudMessagingPluginRegistrant.class.getCanonicalName();
if (registry.hasPlugin(key))
return true;
registry.registrarFor(key);
return false;
您必须在 app/src/main/AndroidManifest.xml 中进行一些更改
<application android:name=".Application"
<activity android:name=".MainActivity"
只需更改应用程序名称和活动名称,其余内容在 AndroidManifest.xml 中相同
【讨论】:
【参考方案4】:仅供参考。在 MainActivity.java 中使用 io.flutter.embedding
包时
您可以使用以下方式注册各种插件
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.plugins.util.GeneratedPluginRegister;
public class MainActivity extends FlutterActivity
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine)
GeneratedPluginRegister.registerGeneratedPlugins(flutterEngine);
【讨论】:
以上是关于Flutter:尝试向 FlutterEngine 自动注册插件,但找不到并调用 GeneratedPluginRegistrant的主要内容,如果未能解决你的问题,请参考以下文章
当我想设置后台任务时,flutter -i 出错(PluginRegistry 无法转换为 FlutterEngine ...)
Flutter Android 端 FlutterEngine Java 相关流程源码分析
Flutter Android 端 FlutterEngine Java 相关流程源码分析
Flutter Android 端 FlutterEngine Java 相关流程源码分析