2015-04-15 53 views
1

我正在構建一個JNI應用程序。收到回調後,從JNI調用Java方法

從我的JNI代碼中,我想調用一個更新UI的java函數。

基本上當我收到一個回調,並試圖讓參考的環境我得到的類型的錯誤: Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1), thread 1869 (ALooper)

我讀過不好有一個靜態參考ENV,但我可以有一個靜態引用到JavaVM

你能告訴我我做錯了什麼?

非常感謝您的時間

jclass globalClass = NULL; 
static JavaVM* mVm = NULL; 

jint JNI_OnLoad(JavaVM* vm, void* reserved) { 
    mVm = vm; 
    JNIEnv* env; 

    if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_6) != JNI_OK) { 
     __android_log_print(ANDROID_LOG_DEBUG, "nativeTAG", "get env failed"); 
     return -1; 
    } 
    return JNI_VERSION_1_6; 
} 

static void callMyJavaFunction() { 
    JNIEnv* env; 
    jclass playerUtils = NULL; 
    jmethodID updatePlayerStatus = NULL; 
    jobject myObject = NULL; 

    if ((*mVm)->GetEnv(mVm, (void **) &env, JNI_VERSION_1_6) != JNI_OK) { 
     __android_log_print(ANDROID_LOG_DEBUG, "jajaja", ">>NATIVE jni failed"); 

     /*ERROR A/libc(1853): Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1), thread 1869 (ALooper)*/ 
    } 

    playerUtils = (*env)->FindClass(env, 
     "com/example/customviewcircles/nativeaudio/PlayerUtils"); 

    if (playerUtils != NULL) { 
     updatePlayerStatus = (*env)->GetMethodID(env, playerUtils, 
      "updatePlayerStatus", "()V"); 

     if (updatePlayerStatus != NULL) { 
      myObject = (*env)->NewObject(env, playerUtils, updatePlayerStatus); 

      (*env)->CallVoidMethod(env, myObject, updatePlayerStatus); 
     } 
    } 
} 

void myCallBackFunction() { 
    callMyJavaFunction(); 
} 
+0

究竟在什麼地方發生段錯誤?當你調用'FindClass' .. ..? – Michael

+0

回調是否在未連接到VM的線程上出現?如果是這樣,'GetEnv'將返回'JNI_EDETACHED','env'將會失效。在這種情況下,你需要在使用'env'後調用'AttachCurrentThread'(和'DetachCurrentThread')。 – Michael

+0

我得到Log >> NATIVE jni失敗,然後FindClass()上的錯誤 –

回答

1

一個明智的隊友後告訴我,我得到了它的方式。

萬一有人需要它:

jclass globalClass = NULL; 
static JavaVM* mVm = NULL; 

jint JNI_OnLoad(JavaVM* vm, void* reserved) { 

    mVm = vm; 

    JNIEnv* env; 
    jclass playerUtils = NULL; 

    if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_6) != JNI_OK) { 
     __android_log_print(ANDROID_LOG_DEBUG, "jajaja", ">>NATIVE jni failed"); 
     return -1; 
    } 
    playerUtils = (*env)->FindClass(env, 
      "com/example/customviewcircles/nativeaudio/PlayerUtils"); 

    if (playerUtils != NULL) { 

     globalClass = (*env)->NewGlobalRef(env, playerUtils); 
    } 
    return JNI_VERSION_1_6; 
} 

void callMyJavaFunction() { 

    JNIEnv* env; 
    jmethodID updatePlayerStatus = NULL; 
    jobject myObject = NULL; 

    if((*mVm)->AttachCurrentThread(mVm, &env, NULL) == JNI_OK) { 
     __android_log_print(ANDROID_LOG_DEBUG, "jajaja", ">>NATIVE attached successfully"); 
    } 

    if (globalClass != NULL) { 

     __android_log_print(ANDROID_LOG_DEBUG, "jajaja", 
          ">>NATIVE globalclass not null"); 

     updatePlayerStatus = (*env)->GetMethodID(env, globalClass, 
       "updatePlayerStatus", "()V"); 

     if (updatePlayerStatus != NULL) { 

      myObject = (*env)->NewObject(env, globalClass, updatePlayerStatus); 
     } 
    } 
    (*mVm)->DetachCurrentThread(mVm); 

} 

void myCallBackFunction() { 
    callMyJavaFunction(); 
}