-- 作者:wangxinxin
-- 發布時間:2010-12-3 11:51:12
-- Android學習開發4--Android在C++中調用java(3)
5.2 java類的實例化 都知道java需要 obj var = new obj();這樣一個過程,我們在C++中調用java類的成員函數,當然也要先示例話一個類。 示例化的函數如下所示 jobject getInstance(JNIEnv* env, jclass obj_class) { jmethodID construction_id = env->GetMethodID(obj_class, "<init>", "()V"); jobject obj = env->NewObject(obj_class, construction_id); return obj; } 這個函數中的env表示環境參數,jclass表示一個java類的句柄。 jmethodID construction_id = env->GetMethodID(obj_class, "<init>", "()V"); GetMethodID的參數分別為(類句柄,方法名稱,參數名稱) 這個是為了獲取java類中某個方法的句柄,有一點需要特別注意的,在獲取構造方法的句柄和別的方法的句柄是不一樣的。 獲取一般方法的句柄所填寫“方法名稱”參數直接就是這個方法的名稱,而構造函數的話就必須填寫"<init>"。除了這點區別外,就沒有區別了。 而我們的“參數名稱”似乎寫的就有些奇怪了。但是細說下他的規律也就不怪了。 參數名稱的書寫規則為 (參數1類型,參數2類型….)返回類型。而相應類型的表示如下所示

比如我們要找個int func(double)類型的函數,就該這么寫: jmethodID construction_id = env->GetMethodID(obj_class, " func ", "(D)I"); 找到了構造函數的方法之后我們直接調用構造函數,然后把生成的類返回即可 jobject obj = env->NewObject(obj_class, construction_id); 其中obj_class為類的句柄construction_id為構造函數的句柄,而類的實例被該函數返回。
5.3 調用java類的其他函數 JNIEXPORT jstring JNICALL Java_com_hm_hello_CActivityMain_stringFromJNI (JNIEnv* env, jobject) { jstring str; jclass java_class = env->FindClass("com/hm/hello/CForCall"); if (java_class == 0) { return env->NewStringUTF("not find class!"); } jobject java_obj = getInstance(env, java_class); if (java_obj == 0) { return env->NewStringUTF("not find java OBJ!"); } jmethodID java_method = env->GetMethodID(java_class, "GetJavaString", "()Ljava/lang/String;"); if(java_method == 0) { return env->NewStringUTF("not find java method!"); } str = (jstring)env->CallObjectMethod(java_obj, java_method); return str; } 看完了構造函數的介紹,這段代碼其實很容易就看懂了,我們發現調用java中的函數的步驟無非幾步: 1找到類句柄 2找到類的方法的句柄 3實例化類 4調用實例化類的方法。 而以上代碼中只有一段沒說過,就是 jclass java_class = env->FindClass("com/hm/hello/CForCall"); 看名字就知道,是在找相應的類的句柄,其中com.hm.hello準備調用類的完整包名(把.轉換為/),而CforCall就是我們要調用的類的名稱。 至此,編譯,然后在Android調試,可愛的機器人又出現了,哈哈,屏幕上顯示出現了12345,成功!
|