If I alter Juce’s JNI_Onload
to this:
extern "C" jint JNIEXPORT JNI_OnLoad (JavaVM* vm, void*)
{
// Huh? JNI_OnLoad was called two times!
jassert (androidJNIJavaVM == nullptr);
androidJNIJavaVM = vm;
auto* env = getEnv();
// register the initialisation function
auto juceJavaClass = env->FindClass("com/rmsl/juce/Java");
__android_log_write(ANDROID_LOG_DEBUG, "Tag", "finding MainActivity");
auto S = env->FindClass("com/my_app/flutter_app/MainActivity");
__android_log_write(ANDROID_LOG_DEBUG, "Tag", "finding MainActivity END");
if (!S) {
__android_log_write(ANDROID_LOG_ERROR, "Tag", "finding MainActivity END");
} else {
__android_log_write(ANDROID_LOG_DEBUG, "Tag", "DID find MainActivity");
}
it works without any problem. That is, the class MainActivity
is found. However, the same line
auto mainActivityClass1 = env->FindClass("com/my_app/flutter_app/MainActivity");
on
MyJuceApp() {
JNIEnv* env = juce::getEnv();
auto mainActivityClass1 = env->FindClass("com/my_app/flutter_app/MainActivity");
(where START_JUCE_APPLICATION (MyJuceApp)
gives
A/zygote64: java_vm_ext.cc:523] JNI DETECTED ERROR IN APPLICATION: JNI CallBooleanMethodV called with pending exception java.lang.ClassNotFoundException: Didn't find class "com.my_app.flutter_app.MainActivity" on path: DexPathList[[dex file "InMemoryDexFile[cookie=[0, 547943543104]]"],nativeLibraryDirectories=[/system/lib64, /system/vendor/lib64]]
It looks like when JNI_Onload
is called, it’s called from the java thread. Then, JNI_Onload
calls some juce internal things that starts the app by calling MyJuceApp
, where things fail. I think it fails because MyJuceApp
is initialized from another thread.
So, the class definetly exists because JNI_Onload
finds it. But when MyJuceApp
constructor is called, it cannot find the same class anymore.
I also tried attaching the thread:
JNIEnv* env = juce::getEnv();
JavaVM* vm;
env->GetJavaVM(&vm);
JavaVMAttachArgs args;
args.version = JNI_VERSION_1_6;
args.name = nullptr;
args.group = nullptr;
JNIEnv* env2 = juce::getEnv();
vm->AttachCurrentThread(&env2, &args);
auto mainActivityClass1 = env2->FindClass("com/my_app/flutter_app/MainActivity");
and got the same problem.
ps: env->FindClass("java/lang/String")
works where env->FindClass("com/my_app/flutter_app/MainActivity")
does not, which makes things even more confusing. But the class name is correct, because it’s found on JNI_Onload
.