JNI呼叫Java方法
阿新 • • 發佈:2019-02-16
《Pro Android C++ with the NDK》學習筆記
- 獲取方法ID
- 呼叫方法
- JNI呼叫Java靜態方法案例
與域一樣,Java中有兩類方法:例項方法和靜態方法。JNI提供訪問兩類方法的函式,例如:
public class JavaClass {
// 例項方法
private String instanceMethod(){
return "Instance Method";
}
// 靜態方法
private static String staticMethod(){
return "StaticMethod";
}
}
一、獲取方法ID
JNI提供了用方法ID訪問兩類方法的途徑,可以用給定例項的class物件獲得方法ID。用GetMethodID函式獲得例項方法的方法ID,例如:
jmethodID instanceMethodId;
instanceMethodId = (*env)->GetMethodID(env,clazz,"instanceMethod","()Ljava/lang/String;");
用GetStaticMethodID函式獲得靜態域的方法ID,例如:
jmethodID staticMethodId;
staticMethodId = (*env)->GetStaticMethodID(env,clazz,"staticMethod","()Ljava/lang/String;");
兩個函式的最後一個引數均表示方法描述符,在Java中表示方法簽名。
二、呼叫方法
可以以方法ID為引數通過CallMethod類函式呼叫實際的例項方法,例如:
1、呼叫例項方法
jstring instanceMethodResult;
instanceMethodResult = (*env)->CallStringMethod(env,instance,"instanceMethodId");
2、呼叫靜態方法
jstring staticMethodResult;
staticMethodResult = (*env)->CallStaticStringMethod(env,clazz,"staticMethodId" );
三、JNI呼叫Java靜態方法案例
HelloJni.java
public class HelloJni extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
callJavaStaticMethod();
}
public native String callJavaStaticMethod();
static {
System.loadLibrary("hello-jni");
}
// 靜態方法
private static String staticMethod() {
return "StaticMethod Castiel";
}
}
hellojni.c
#include <string.h>
#include <jni.h>
#include <android/log.h>
JNIEXPORT void JNICALL
Java_com_example_hellojni_HelloJni_callJavaStaticMethod(JNIEnv *env, jclass type) {
jclass jniClass = (*env)->FindClass(env, "com/example/hellojni/HelloJni");
if (NULL == jniClass) {
__android_log_print(ANDROID_LOG_INFO,"HelloJni","can't find jclass");
return;
}
jmethodID getMId = (*env)->GetStaticMethodID(env, jniClass, "staticMethod",
"()Ljava/lang/String;");
if (NULL == getMId) {
__android_log_print(ANDROID_LOG_INFO,"HelloJni","can't find method getStringFromStatic from JniClass");
return;
}
jstring result = (*env)->CallStaticObjectMethod(env, jniClass, getMId);
const char *resultChar = (*env)->GetStringUTFChars(env, result, NULL);
(*env)->DeleteLocalRef(env, jniClass);
(*env)->DeleteLocalRef(env, result);
__android_log_print(ANDROID_LOG_INFO,"HelloJni",resultChar);
}
編譯後執行程式,可以看到日誌中成功列印了我們獲取的Java方法:StaticMethod Castiel。