V
V
vadim08722017-05-23 14:09:37
Android
vadim0872, 2017-05-23 14:09:37

Threads in android ndk development?

I am developing an android application using ndk. I read in the book that if a thread is created in the low-level part of the application, this thread must be attached to the JVM (it is clear that in Davlik android, but not the essence) so that you can access the JVM through a pointer, respectively, you need to call the AttachCurrentThread (Jnienv * env ) and, accordingly, use this function to get a pointer to the JVM.
For these purposes, I wrote two methods that attach a stream if it is not attached, and then detach it.

JavaVM *javaVM;

boolean GetJniEnvAndAttach(JNIEnv *jniEnv){

    int resault = (javaVM->GetEnv((void **) &jniEnv, JNI_VERSION_1_6));
    if (resault == JNI_EDETACHED){
        if (javaVM->AttachCurrentThread(&jniEnv,0) == JNI_OK){
            LOGI("Thread attach to JVM");
            return true;
        }
    } else {
        LOGI("Thread wasn`t attach");
        }
        return false;
    }
}

void Detach(boolean isAttach){
    if (isAttach){
        javaVM->DetachCurrentThread();
    }
}

Before the code that uses the pointer to jvm, GetJniEnvAndAttach is called, and at the end of Detach.
JavaVM is initialized when the application starts:
JNIEXPORT jint JNICALL JNI_OnLoad(
        JNIEnv *env) {

    JavaVM *jmv = NULL;
    env->GetJavaVM(&jmv);
    javaVM = jmv;
    return JNI_OK;

}

The essence of the question is that if I create a low-level thread, then everything attaches and detaches as it should, and if I call these functions from a thread created by jvm, everything falls with the error: "A / libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 12345"
What's the problem?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
vadim0872, 2017-06-01
@vadim0872

Perhaps someone will be interested, but I figured out the problem.
It turned out that I am not very friendly with pointers in C, as an argument it was necessary to pass not just a pointer to jnienv, but a pointer to a pointer, but it didn’t quite work, so I added the local variable localenv * Jnienv inside the GetJniEnvAndAttach method; which I used further inside the function, and before returning from the function assigned it to the pointer passed in the argument: &jnienv = localenv;

boolean GetJniEnvAndAttach(JNIEnv **jniEnv){

    JNIEnv *localEnv = NULL;

    if (javaVM->GetEnv((void **) &localEnv, JNI_VERSION_1_6) == JNI_EDETACHED){
        if (javaVM->AttachCurrentThread(&localEnv,0) == JNI_OK){
            *jniEnv = localEnv;
            LOGI("Thread attach to JVM");
            return true;
        }
    } else {
        *jniEnv = localEnv;
        LOGI("Thread wasn`t attach");

        return false;
    }
    return false;
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question