I am calling a java method from C++ in android app. Works fine in debug but GetMethodID fails in release build.
// Java
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
//...
showKeyboard();
}
public void showKeyboard()
{
Log.i("my_app", "MainActivity::showKeyboard");
//...
}
}
// C++
JavaVM* gJvm; // Saved in JNI_OnLoad()
jobject gMainActivity; // Saved in call Java -> C++
// using JNIEnv->NewGlobalRef(mainActivity)
void my_thread_func() {
JNIEnv* jniEnv = nullptr;
gJvm->AttachCurrentThread(&jniEnv, nullptr);;
jclass activityClass = jniEnv->GetObjectClass(gMainActivity);
jmethodID methodId = jniEnv->GetMethodID(activityClass, "showKeyboard", "()V");
// Debug build: methodId is valid
// Release build: methodId is null
}
showKeyboard is called from onCreate only for debug purposes. I can see the line "MainActivity::showKeyboard" in the output. Also it works as expected in debug build.
I suspect java optimization kicks in and removes the method in release. Although it's called in onCreate, it may just get inlined. I tried to add 50+ lines of log prints hoping to discourage inlining but it didn't change anything.
Is there a way to disable java optimization for this method? Or how else can I troubleshoot it?
Yes, compiling code in release mode turns on Proguard minification and obfuscation. If you look at the documentation, you will find several options:
showKeyboard
method. This will get picked up by the default proguard ruleset and prevent the method from being renamed or removed.-keep public class com.example.MainActivity {
public void showKeyboard();
}