Liu Silong
Liu Silong

Reputation: 5532

Flutter build release APK get NoSuchMethodException error

I encountered a problem when upgrading the Flutter SDK. I used to use 1.9.x (there is no problem below). Now I upgrade to v1.12.13 + hotfix.9 or 1.17.0 to reproduce this problem (I have only tried These two versions), the problem is as follows:

Now I use the v1.17.0 SDK to create a plug-in, and then use the reflection call method in the plug-in. The code is as follows:

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");
    }
  }

The Person class as follows:

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();
        }
    }
}

Part of Flutter's code is as follows

flutterplugin17.dart

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

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

Then if it is run directly (Click the debug button to run in Android Studio), it is OK, and the reflection method can be correctly called.

Using Android Studio to package Release APK (release) is also no problem.

Build -> Generate Signed Bundle or APK

But when I use the Flutter command to package the APK (release), the reflection method in the plugin cannot be called at this time. adb logcat is as follows:

Packaging commands : flutter build apk --release

error.png

There is also a situation where the above problem occurs. When another library is used in a plugin and this library is obfuscated, this time the above error will occur if the method in this obfuscated library is called.

flutter doctor:

doctor.jpg

I don’t know why this problem occurs when using the flutter command to package the release APK, thanks.

github repository: https://github.com/liusilong/flutter_plugin_17


I used the following three ways to package apk and then opened these apk in android studio for comparison:

  1. The flutter version is 1.17, packaged with Android studio (Build -> Generate Signed Bundle or APK), the dex file is parsed as follows:

image.png

  1. The flutter version is 1.17, packaged with Flutter commands(flutter build apk --release), the dex file is parsed as follows:

image.png

  1. The flutter version is 1.9.1+hotfix.6, packaged with Flutter commands(flutter build apk --release), the dex file is parsed as follows:

image.png

Upvotes: 3

Views: 1084

Answers (2)

Liu Silong
Liu Silong

Reputation: 5532

I know what the problem is. I am using Android Studio3.6, the documentation says When you use Android Studio 3.4 or Android Gradle plugin 3.4.0 and higher, R8 is the default compiler

There are two ways to solve it:

add proguard-rules.pro file to project/app/proguard-rules.pro

The first solution(Not using R8):

  1. In the project/gradle.properties file, Set this property android.enableR8 to false, as follow:
org.gradle.jvmargs=-Xmx1536M
android.enableR8=false
android.useAndroidX=true
android.enableJetifier=true
  1. In the project/app/proguard-rules.pro file, customize the code to keep:
-keep class com.lsl.flutterplugin17.* {*;}
  1. In the project/app/build.gradle file, add the code as follow:
android {
   ...

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

        }
    }
   ...
}

Use flutter command flutter build apk --release to pack, the dex file is parsed as follows:

image.png

The second solution(Use R8):

1.In the project/app/proguard-rules.pro file, add the code as follow:

-dontobfuscate
-dontshrink
  1. In the project/app/build.gradle file, add the code as follow:
android {
   ...

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

        }
    }
   ...
}

Use flutter command flutter build apk --release to pack, the dex file is parsed as follows:

image.png

Upvotes: 3

Gonzalo Gauto
Gonzalo Gauto

Reputation: 181

Maybe you need to accept the android licenses to build a release apk?

Upvotes: -1

Related Questions