Flutter 构建发布版 APK 时出现 NoSuchMethodException 错误。

3
我在升级Flutter SDK时遇到了问题。 我之前使用的是1.9.x(以下没有问题)。 现在我升级到v1.12.13+hotfix.91.17.0以重现此问题(我只尝试了这两个版本),问题如下:
现在我使用v1.17.0 SDK创建一个插件,然后在插件中使用反射调用方法。 代码如下:

Flutterplugin17Plugin.java

  @Override
  public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
    if (call.method.equals("personName")) { // Reflection call method
      person.execute(call.method);
      result.success("success");
    }
  }

Person类如下所示:

Person.java

public class Person {
    private static final String TAG = "Person";

    // This method will be called by reflection
    public void personName() {
        Log.e(TAG, "personName: call personName method....");
    }

    public void execute(String methodName) {
        try {
            Method method = Person.class.getDeclaredMethod(methodName);
            method.invoke(Person.this);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Flutter的代码如下所示。

flutterplugin17.dart

static Future<void> callMethod() async{
  await _channel.invokeMethod("personName");
}

// The method is called when the button is clicked
await Flutterplugin17.callMethod();


然后,如果直接运行(点击Android Studio中的“调试”按钮),是可以的,并且可以正确调用反射方法。
使用Android Studio打包Release APK(发布)也没有问题。
但是,当我使用Flutter命令打包APK(发布)时,此时插件中的反射方法无法被调用。adb logcat如下所示:
打包命令:flutter build apk --release

error.png

当插件中使用了另一个库并且该库被混淆时,也会出现上述问题。如果调用混淆后库中的方法,则会出现上述错误。
flutter doctor:

doctor.jpg

我不知道为什么使用Flutter命令打包发布APK时会出现这个问题,谢谢。
GitHub存储库:https://github.com/liusilong/flutter_plugin_17
我使用了以下三种方法来打包apk,然后在Android Studio中打开这些apk进行比较:
  1. Flutter版本为1.17,使用Android Studio(Build -> Generate Signed Bundle or APK)进行打包,dex文件的解析如下:

image.png

  1. Flutter的版本为1.17,使用Flutter命令(flutter build apk --release)打包时,dex文件解析如下:

image.png

  1. Flutter版本为1.9.1+hotfix.6,使用Flutter命令(flutter build apk --release)打包,dex文件解析如下:

image.png

2个回答

2
我知道问题出在哪里。我正在使用Android Studio3.6,文档中写道:当您使用Android Studio 3.4或Android Gradle插件3.4.0及更高版本时,R8是默认编译器
有两种解决方法:

proguard-rules.pro文件添加到project/app/proguard-rules.pro

第一种解决方案(不使用R8):

  1. project/gradle.properties文件中,将此属性android.enableR8设置为false,如下所示:
org.gradle.jvmargs=-Xmx1536M
android.enableR8=false
android.useAndroidX=true
android.enableJetifier=true

project/app/proguard-rules.pro 文件中,自定义代码以保留以下内容:
-keep class com.lsl.flutterplugin17.* {*;}

project/app/build.gradle文件中添加以下代码:
android {
   ...

    buildTypes {
        release {
            ...
            // add new line
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

        }
    }
   ...
}

使用Flutter命令 flutter build apk --release 进行打包,解析dex文件的过程如下:

image.png

第二种解决方法(使用R8):

1.在项目/app/proguard-rules.pro文件中添加以下代码:

-dontobfuscate
-dontshrink

project/app/build.gradle文件中添加以下代码:
android {
   ...

    buildTypes {
        release {
            ...
            // add new line
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

        }
    }
   ...
}

使用flutter命令flutter build apk --release进行打包,dex文件解析如下:

image.png

以下是相关链接:

-1
也许您需要接受 Android 许可证才能构建发布 APK?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接