2011-12-16 19 views
10

Tôi muốn gọi Java API từ chuỗi NDK C++, nhưng env-> FindClass() trả về 0. Nhưng khi tôi gọi Java API trong chủ đề chính, nó hoạt động tốt. Tôi đã gọi AttachCurrentThread() trong thread, bất cứ ai có thể giúp tôi?Làm cách nào để gọi API Java từ chuỗi NDK C++?

Đây là mã nguồn:

JAVA Mã sản phẩm:

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

C++ Mã sản phẩm:

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); 
} 

Trả lời

5

tôi đã giải quyết nó ngay bây giờ. Trong chuỗi gốc NDK, chỉ có thể gọi API Java tĩnh. Nếu bạn gọi env-> FindClass(), nó sẽ kích hoạt một ngoại lệ. http://android.wooyd.org/JNIExample đã cung cấp thông tin chi tiết.

0

Đề xuất xem qua số AttachCurrentThread.

Dưới đây là một số mẫu mã để làm điều đó:

// 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__); 
} 
Các vấn đề liên quan