0

I have this code:

JNIEXPORT void package_MyAPI_callback(JNIEnv *env, jobject thiz, jobject caller) {
    JavaVM *vm;
    env->GetJavaVM(&vm);
    jclass callbackClass = (jclass) env->NewGlobalRef(env->FindClass("package/TimeLoadedListenerUIThread"));
    jobject cachedCaller = (jobject) env->NewGlobalRef(caller);
    jmethodID javaCallback = env->GetMethodID(callbackClass, "onTimeLoaded", "(Z)V");

    CppSetCallback([=] {
        JNIEnv *bgEnv;
        vm->AttachCurrentThread(&bgEnv, NULL);        
        bgEnv->CallVoidMethod(cachedCaller, javaCallback, false);

        bgEnv->DeleteGlobalRef(callbackClass);
        bgEnv->DeleteGlobalRef(cachedCaller);
        //vm->DetachCurrentThread();
    });
}

And somewhere in Kotlin code:

override fun onTimeLoaded(resetToCurrentTime: Boolean) {
    activity.runOnUiThread { 
        activity.updateTimeSelector(resetToCurrentTime) }
    }
}

CppSetCallback sets callback (as functional) to internal core of app. There, the functional is called from std::thread.

This code runs, but I am not sure if it is correct, because If I call vm->DetachCurrentThread(); app crashes. How should I call detach, or when?

Martin Perry
  • 9,232
  • 8
  • 46
  • 114
  • It seems like the attachcurrentthread method call is missing one parameter. I wonder if that can be the cause – Claudio Corsi Mar 05 '18 at 13:03
  • Wait it looks like you need to pass the vm parameter to the attach and detach calls. – Claudio Corsi Mar 05 '18 at 13:05
  • @ClaudioCorsi: You may be thinking of the C API. The code in the question is C++, so the `JavaVM*` is passed through `this` (i.e. `vm->...`). – Michael Mar 05 '18 at 20:29
  • 1
    See [this answer](https://stackoverflow.com/questions/30026030/what-is-the-best-way-to-save-jnienv/30026231#30026231) for an example of a safe way of getting a `JNIEnv*` from any thread. – Michael Mar 05 '18 at 20:39
  • @Michael Thanks, solved the problem – Martin Perry Mar 06 '18 at 06:34

0 Answers0