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 相关流程源码分析

Flutter Android 端 FlutterEngine Java 相关流程源码分析

集成 Flutter 到现有项目,并实现使用单个 FlutterEngine 管理多个入口