android NDK 開發(3)
阿新 • • 發佈:2018-12-14
1.native層呼叫java層static方法
//java層定義方法 public native static void request(); //native層執行完request後回撥此方法 public static void nativeCallBack() { System.out.println("nativeCallBack"); //native層實現 JNIEXPORT void JNICALL Java_com_hd_jni_JNITest_request(JNIEnv *env, jclass jclass1) { //調java方法 jmethodID methodid = (*env)->GetStaticMethodID(env, jclass1, "nativeCallBack", "()V"); (*env)->CallStaticVoidMethod(env, jclass1, methodid, NULL); } //測試程式碼 private void testCallback() { JNITest.request(); }
2.native層修改java層物件成員變數值,包括直接修改成員變數和呼叫成員方法修改
//java層定義 public native static void modifyValue(Student student); //native層實現 JNIEXPORT void JNICALL Java_com_hd_jni_JNITest_modifyValue (JNIEnv *env, jclass jclass1, jobject obj) { //根據傳入的物件獲得對應的class jclass objClass = (*env)->GetObjectClass(env, obj); //修改名字 jfieldID nameid = (*env)->GetFieldID(env, objClass, "name", "Ljava/lang/String;"); if (nameid == NULL) { return; } jstring nameStr = (jstring) (*env)->GetObjectField(env, obj, nameid); const char *name = (*env)->GetStringUTFChars(env, nameStr, NULL); (*env)->ReleaseStringUTFChars(env, nameStr, name); nameStr = (*env)->NewStringUTF(env, "name has modify"); if (nameStr == NULL) { return; } (*env)->SetObjectField(env, obj, nameid, nameStr); //修改性別 jmethodID sexMethodid = (*env)->GetMethodID(env, objClass, "setSex", "(I)V"); (*env)->CallVoidMethod(env, obj, sexMethodid, 2); } //測試程式碼 private void testModifyValue() { Student student = new Student("lisi", 0); JNITest.modifyValue(student); Toast.makeText(JNITestActivity.this, "name=" + student.name + ",sex=" + student.sex, Toast.LENGTH_LONG).show(); }
3.自定義native方法名
1)定義方法結構體
// 結構體,分別是java層的函式名稱,簽名,對應的函式指標
static JNINativeMethod gMethods[] = {
{"testChangeString", "(Ljava/lang/String;)Ljava/lang/String;", (void *) testChangeString},
};
2)自己實現JNI_OnLoad,寫在任何一個.c檔案都可以
JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) { JNIEnv *env = NULL; jint result = -1; if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_4) != JNI_OK) { return -1; } /* * 如果要註冊,需要兩步, * 首先FindClass, * 然後RegisterNatives */ char className[20] = {"com/hd/jni/JNITest"}; jclass clazz = (*env)->FindClass(env, (const char *) className); if ((*env)->RegisterNatives(env, clazz, gMethods, sizeof(gMethods) / sizeof(gMethods[0])) != JNI_OK) { printf("register native method failed!\n"); return -1; } //一定要返回版本號,否則會出錯。 result = JNI_VERSION_1_4; return result; }