【问题标题】:Calling Java code from Flutter throws Unhandled Exception: MissingPluginException(No implementation found for method...)从 Flutter 调用 Java 代码会引发未处理的异常:MissingPluginException(No implementation found for method...)
【发布时间】:2021-10-28 04:44:06
【问题描述】:

我正在开发一个必须调用 java 函数的颤振项目。所以,我这样定义了我的 MainActivity.java:

package com.manager.nlp;

import android.os.Bundle;
import android.content.Intent;
import android.os.PowerManager;
import android.os.Build.VERSION;
import androidx.annotation.NonNull;
import android.content.IntentFilter;
import android.content.ContextWrapper;
import android.os.Build.VERSION_CODES;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugins.GeneratedPluginRegistrant;
import io.flutter.embedding.android.FlutterActivity;

public class MainActivity extends FlutterActivity {
    private static final String CHANNEL = "analisisSintactico";

    public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
        GeneratedPluginRegistrant.registerWith(flutterEngine);

        new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)
                .setMethodCallHandler((call, result) -> {
                    if (call.method.equals("method")) {
                        result.success("value1");
                    } else {
                        result.success("value2");
                    }
                });
    }
}

我称它为从 dart 的主文件中执行此操作:

(我会跳过不重要的,比如其他小部件和那些东西)

import 'package:flutter/material.dart';
import 'dart:io';
import 'package:flutter/services.dart';
class PaginaHome extends StatefulWidget {
  const PaginaHome({Key key}) : super(key: key);

  @override
  _PaginaHomeState createState() => _PaginaHomeState();
}

class _PaginaHomeState extends State<PaginaHome> {
  static const cajaNegra = const MethodChannel('analisisSintactico');
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: new Column(children: <Widget>[
              IconButton(
                  onPressed: () {
                    invocarAJava();
                  }
                  ...
              )
         ...
         )
    }
    Future<void> invocarAJava() async {
       String valor = await cajaNegra.invokeMethod('method');
       print(valor);
    }
}

当点击那个图标按钮时,我得到这个错误:

E/flutter (9060): [错误:flutter/lib/ui/ui_dart_state.cc(199)] 未处理的异常:MissingPluginException(未找到实现 对于通道 analisisSintactico 上的方法方法)E/flutter(9060):#0 MethodChannel._invokeMethod (包:flutter/src/services/platform_channel.dart:156:7) E/flutter ( 9060):E/颤振(9060):#1
_PaginaHomeState.invocarAJava (package:holamundo/main.dart:146:20) E/flutter (9060):

如果我运行“flutter doctor -v”,它说一切都是正确的

我还尝试执行flutter clean,然后flutter run,从调试android模拟器中删除了de apk。它仍然显示相同的错误。

我知道文件正在被评估,因为如果我写了一些愚蠢的东西,它会检测到错误。但是,不知何故,它无法识别它正在调用的方法。还尝试了其他名称的通道和方法。

最后,这是我的 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.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
apply plugin: 'com.google.gms.google-services'

android {
    compileSdkVersion 30

    sourceSets {
        main.java.srcDirs += 'src/main/kotlin'
        main.java.srcDirs += 'src/main/java'
    }

    defaultConfig {
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId "com.example.holamundo"
        minSdkVersion 21
        targetSdkVersion 30
        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

            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

flutter {
    source '../..'
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}

如果有人知道是什么问题导致我无法调用我的 java 代码,我很乐意接受任何建议。谢谢。

【问题讨论】:

    标签: java android flutter dart channels


    【解决方案1】:

    1- 我正在写 kotlin 方面,但我认为问题是一样的。将您的方法作为插件方法移动到另一个 java 文件,如下所示:

    class AnalisisSintacticoPlugin(
            private val registrar: Registrar
    ) : MethodCallHandler,
            PluginRegistry.ActivityResultListener {
    
        private lateinit var _result: MethodChannel.Result
    
        private lateinit var channel: MethodChannel
    
        companion object {
            @JvmStatic
            fun registerWith(registrar: Registrar) {
                val channel = MethodChannel(registrar.messenger(),"analisisSintactico")
                val plugin = FlutterScreenRecordingPlugin(registrar)
                channel.setMethodCallHandler(plugin)
                registrar.addActivityResultListener(plugin)
            }
        }
    
        override fun onMethodCall(call: MethodCall, result: Result) {
            if (call.method == "method") {
                result.success("value1")
            } else {
                result.success("value2")
            }
        }
    }
    

    2- 在你的 MainActivity 中注册它:

    class MainActivity: FlutterActivity() {
        override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
            super.configureFlutterEngine(flutterEngine)
            val shimPluginRegistry = ShimPluginRegistry(flutterEngine)
            com.manager.nlp.AnalisisSintacticoPlugin.registerWith(shimPluginRegistry.registrarFor("com.manager.nlp.AnalisisSintacticoPlugin"))
            GeneratedPluginRegistrant.registerWith(flutterEngine)
        }
    }
    

    编辑1:对于java端:

    1- 在与 MainActivity 相同的文件夹中创建一个名为 AnalisisSintacticoPlugin 的文件。然后传递这个代码:

    package com.manager.nlp;
    
    import androidx.annotation.NonNull;
    import io.flutter.embedding.engine.plugins.FlutterPlugin;
    import io.flutter.plugin.common.MethodCall;
    import io.flutter.plugin.common.MethodChannel;
    import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
    import io.flutter.plugin.common.MethodChannel.Result;
    
    
    public class AnalisisSintacticoPlugin implements FlutterPlugin, MethodCallHandler {
        private MethodChannel channel;
    
        @Override
        public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
            channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "analisisSintactico");
            channel.setMethodCallHandler(this);
        }
    
        @Override
        public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
            if (call.method.equals("method")) {
                result.success("value1");
            } else {
                result.success("value2");
            }
        }
    
        @Override
        public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
            channel.setMethodCallHandler(null);
        }
    }
    

    2- 在 MainActivity 中添加您的插件:

    package com.manager.nlp;
    
    import androidx.annotation.NonNull;
    import org.jetbrains.annotations.NotNull;
    
    import io.flutter.embedding.engine.FlutterEngine;
    import io.flutter.embedding.android.FlutterActivity;
    
    public class MainActivity extends FlutterActivity {
        @Override
        public void configureFlutterEngine(@NonNull @NotNull FlutterEngine flutterEngine) {
            super.configureFlutterEngine(flutterEngine);
            flutterEngine.getPlugins().add(new com.manager.nlp.AnalisisSintacticoPlugin());
        }
    }
    

    3- 如果没有,请将 AndroidManifest.xml 中的活动名称更改为“.MainActivity”

    <activity
       android:name=".MainActivity" 
    

    4- 确保 AndroidManifest.xml 中的元数据与此完全相同:

    <meta-data
        android:name="flutterEmbedding"
        android:value="2" />
    

    【讨论】:

    • 我从来没有在 kotlin 中写过代码。它们有点相似,但你知道如何在 java 中完成吗?谢谢
    • 当我找到 Java 的解决方案时,我会更新我的答案并发表评论。我现在正在努力让它发挥作用。
    • 我编辑了我的答案。我尝试了很多解决方案,但最终我想通了 :D 无论如何,这很好,祝我的朋友好运!
    猜你喜欢
    • 1970-01-01
    • 2023-04-03
    • 2021-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-19
    • 2016-05-07
    相关资源
    最近更新 更多