一、編寫流程
-
1、聲明
native
方法 -
2、生成對應的頭文件
使用
javah
命令
- 3、在C/C++文件,引入對應的頭文件,並實現對應的方法
使用
""
而非<>
的方式引入。否則會報以下異常.
error: 'com_canter_ndkdemo3_JNIMethod.h' file not found with <angled> include; use "quotes" instead
如果不知道方法簽名,可以使用 javas -p
命令打印輸出。
C/C++代碼的整體實現流程如下:
找到對應的類–>找到對應的方法–>調用相關的方法–>釋放相關的資源–>應用程序進行調用。
二、靜態方法調用
在 native 層調用 Java 層的靜態方法。還有調用Java層的靜態變量,並更改它的值。
JNIEXPORT void JNICALL Java_com_canter_ndkdemo3_JNIMethod_callStaticMethod__I(JNIEnv *env, jclass jclass1, jint jint1) {
//找到對應的類,需要全路徑。將"." 替換成 "/"
jclass clas_JNIMethod = env->FindClass("com/canter/ndkdemo3/JNIMethod");
if (clas_JNIMethod==NULL) {
return;
}
//獲取對應的方法,靜態和實例方法調用的是不同的api
jmethodID method_StaticMethodId = env->GetStaticMethodID(clas_JNIMethod, "staticMethod","(Ljava/lang/String;)V");
if (method_StaticMethodId == NULL) {
return;
}
jstring data = env->NewStringUTF(" call static method");
if (data == NULL) {
return;
}
//調用相關方法
env->CallStaticVoidMethod(clas_JNIMethod, method_StaticMethodId, data);
//調用靜態變量
jfieldID jfieldID1 = env->GetStaticFieldID(jclass1, "sData", "Ljava/lang/String;");
if (jfieldID1 == NULL) {
return;
}
jstring jstring1 = env->NewStringUTF("native-lib");
//更改值
env->SetStaticObjectField(jclass1, jfieldID1, jstring1);
env->CallStaticVoidMethod(clas_JNIMethod, method_StaticMethodId, data);
//釋放相關的資源
env->DeleteLocalRef(clas_JNIMethod);
env->DeleteLocalRef(data);
env->DeleteLocalRef(jstring1);
}
運行結果:
三、實例方法調用
JNIEXPORT void JNICALL Java_com_canter_ndkdemo3_JNIMethod_callInstanceMethod__I
(JNIEnv *env, jobject jobject1, jint jint1) {
jclass clas_JNIMethod = env->FindClass("com/canter/ndkdemo3/JNIMethod");
if (clas_JNIMethod == NULL) {
return;
}
//找到對應的構造方法
jmethodID construct_Method = env->GetMethodID(clas_JNIMethod, "<init>", "()V");
if (construct_Method == NULL) {
return;
}
//創建對象
jobject jniMethodObj = env->NewObject(clas_JNIMethod, construct_Method, NULL);
if (jniMethodObj == NULL) {
return;
}
//找到對應的實例
jfieldID jfieldID1 = env->GetFieldID(clas_JNIMethod, "address", "Ljava/lang/String;");
if (jfieldID1 == NULL) {
return;
}
jstring addressData = env->NewStringUTF("native call guangxi");
//修改對應的實例
env->SetObjectField(jniMethodObj, jfieldID1, addressData);
//找到對應的實例方法方法
jmethodID jmethodID1 = env->GetMethodID(clas_JNIMethod, "logAddress", "(Ljava/lang/String;)V");
if (jmethodID1 == NULL) {
return;
}
jstring address = env->NewStringUTF("call instance method");
//調用對應的實例方法
env->CallVoidMethod(jniMethodObj, jmethodID1, address);
env->DeleteLocalRef(address);
env->DeleteLocalRef(addressData);
}