2011-12-16 27 views
10

मैं जावा एपीआई को एनडीके सी ++ थ्रेड से कॉल करना चाहता हूं, लेकिन env-> FindClass() वापसी 0। लेकिन जब मैं जावा एपीआई को मुख्य थ्रेड में कॉल करता हूं, तो यह अच्छी तरह से काम करता है। मैंने थ्रेड में अटैचकंटेंट थ्रेड() को पहले ही कॉल कर दिया है, क्या कोई मेरी मदद कर सकता है?एनडीके सी ++ थ्रेड से जावा एपीआई को कैसे कॉल करें?

जावा कोड:

public class simple_test extends Activity { 
    ... 
    // This functin will be called in C++ 
    public void PrintNdkLog(String slog) { 
     Log.e(logTagNDK, slog); 
     return; 
    } 
} 

सी ++ कोड:

static JavaVM* g_JavaVM = NULL; 

jobject getInstance(JNIEnv *env, jclass obj_class) 
{ 
    jmethodID c_id = env->GetMethodID(obj_class, "<init>", "()V"); 
    jobject obj = env->NewObject(obj_class, c_id); 
    return obj; 
} 

// JNI OnLoad 
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) 
{ 
    g_JavaVM = jvm; 
    return JNI_VERSION_1_6; 
} 

// Call JAVA API "PrintNdkLog" in this function 
void PrintNdkLog(char *lpLog) 
{ 
    if (g_JavaVM == NULL) 
     return; 

    JNIEnv *env = NULL; 
    g_JavaVM->GetEnv((void**)&env, JNI_VERSION_1_6); 
    if (env == NULL) 
     return; 

    jclass cls = env->FindClass("com/myndk/simple_test"); 
    if (cls != 0) // **cls will be 0 when PrintNdkLog() is called in thread** 
    { 
     LOGE("FindClass error %p", cls); 
    } 
    else 
    { 
     jmethodID mid; 
     jobject obj; 
     obj = getInstance(env, cls); 
     mid = env->GetMethodID(cls, "PrintNdkLog", "(Ljava/lang/String;)V"); 
     if (mid != 0) 
     { 
      jstring jstrMSG = env->NewStringUTF(lpLog); 
      env->CallVoidMethod(obj, mid, jstrMSG); 
     } 
    } 
} 

// Call JAVA API in thread 
static void* thread_test(void* ptr) 
{ 
    JNIEnv *envLocal; 
    int status = g_JavaVM->GetEnv((void **) &envLocal, JNI_VERSION_1_6); 
    if (status == JNI_EDETACHED) 
    { 
     status = g_JavaVM->AttachCurrentThread(&envLocal, NULL); 
     if (status != JNI_OK) 
      LOGE("AttachCurrentThread failed %d",status); 
    } 
    PrintNdkLog("bbb"); // This JAVA callback failed, and printed "FindClass error" 
} 

// Create thread 
int NdkThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam, int nPriority) 
{ 
    PrintNdkLog("aaa"); // This JAVA callback runs well 
    pthread_t pid; 
    pthread_create(&pid, NULL, thread_test, pParam); 
} 

उत्तर

5

मैं अब इसे हल है

यहाँ स्रोत कोड है। एनडीके मूल धागे में, केवल स्थिर जावा एपीआई कॉल कर सकते हैं। यदि आप env-> FindClass() को कॉल करते हैं, तो यह अपवाद ट्रिगर करेगा। http://android.wooyd.org/JNIExample विवरण जानकारी दी।

0

AttachCurrentThread पर एक नज़र डालने का सुझाव दें।

यहाँ करने के लिए एक नमूना कोड है:

// Global variable 
JavaVM *g_jvm = NULL; //Get g_jvm from jni main thread use env->GetJavaVM(&g_jvm); 
jobject g_obj = NULL; //Where the java function exist. (some activity) 

//Get env in thread function and attach the env 
JNIEnv *env; 
if(g_jvm->AttachCurrentThread(&env, NULL) != JNI_OK) 
{ 
    LOGD("%s: AttachCurrentThread() failed", __FUNCTION__); 
} 

const char * fnName ="somFunctionInYourJava"; //which should be "pulic void somFunctionInYourJava(String input);" 
jstring retStr = env->NewStringUTF(str); 
jclass cls = env->GetObjectClass(thiz); 

jmethodID messageMe = env->GetMethodID(cls, fnName, "(Ljava/lang/String;)V"); 
env->CallVoidMethod(thiz, messageMe, retStr); 

//Detach thread and release related resource  
if(g_jvm->DetachCurrentThread() != JNI_OK) 
{ 
    LOGD("%s: DetachCurrentThread() failed", __FUNCTION__); 
} 
संबंधित मुद्दे