public native String getStringFromJni();
public void printHelloWorld(){
Log.d(TAG, "hello world! by unstatic method");
}
public static void printStaticHelloWorld(){
Log.d(TAG, "hello world! by static method");
}
1. jni回調(diào)靜態(tài)方法
JNIEXPORT jstring JNICALL Java_com_dj_jni_jnimodule_NativeHelper_getStringFromJni
(JNIEnv *env, jobject obj){
jclass cls = (*env)->FindClass(env, "com/dj/jni/jnimodule/NativeHelper");
// jclass cls = (*env)->GetObjectClass(env, obj);
jmethodID callback = (*env)->GetStaticMethodID(env, cls, "printStaticHelloWorld", "()V");
(*env)->CallStaticVoidMethod(env, cls, callback);
return (*env)->NewStringUTF(env,"Hello from JNI !");
}
參數(shù)JNIEnv 和 jobject的解釋:
參數(shù)JNIEnv* env實(shí)際上代表了Java環(huán)境,通過(guò)JNIEnv* 這個(gè)指針就可以對(duì)Java端的代碼進(jìn)行操作层扶。
例如調(diào)用java對(duì)象的方法箫章、獲取java對(duì)象的屬性、創(chuàng)建java對(duì)象等等镜会。jobject obj的含義取決于該native方法是不是static檬寂,比如
public native String getStringFromJni();
就不是static
如果native方法是static,obj表示這個(gè)natvie方法所在類的class對(duì)象戳表。因?yàn)閟tatic方法不需要類實(shí)例焰薄。
如果native方法不是static,obj表示這個(gè)native方法所在的類的實(shí)例扒袖。
注意:
回調(diào)static方法,不需要用到obj亩码。只需要通過(guò)(*env)->FindClass(env, "class name");
獲取類class對(duì)象季率。也可以通過(guò)(*env)->GetObjectClass(env, obj)
獲得類class對(duì)象。
然后通過(guò)GetStaticMethodID(env, clazz, name, sig)
和 CallStaticVoidMethod(env, clazz, methodID, args)
調(diào)用static方法描沟。
2. jni回調(diào)非靜態(tài)方法
JNIEXPORT jstring JNICALL Java_com_dj_jni_jnimodule_NativeHelper_getStringFromJni
(JNIEnv *env, jobject obj){
jclass cls = (*env)->GetObjectClass(env, obj);
jmethodID callback = (*env)->GetMethodID(env, cls, "printHelloWorld", "()V");
(*env)->CallVoidMethod(env, obj, callback);
return (*env)->NewStringUTF(env,"Hello from JNI !");
}
回調(diào)非靜態(tài)方法通過(guò)GetMethodID(env, clazz, name, sig)
和 CallVoidMethod (env飒泻,obj, methodID, args)
調(diào)用鞭光。
注意:
CallVoidMethod(env, obj, methodID, args)
的第二個(gè)參數(shù)obj是類的實(shí)例。需要傳入類實(shí)例化后的對(duì)象泞遗。
其對(duì)應(yīng)的java代碼的方式是:
NativeHelper nativeHelper = new NativeHelper();
nativeHelper.printHelloWorld();
CallStaticVoidMethod(env, clazz, methodID, args)
的第二個(gè)參數(shù)clazz是類的class實(shí)例惰许。需要傳入類class對(duì)象。
JNIEnv可以通過(guò)以下幾種方式獲取類class對(duì)象史辙,即jclass:
jclass FindClass(const char* clsName) 根據(jù)類名來(lái)查找一個(gè)類汹买,完整類名。
jclass GetObjectClass(jobject obj) 根據(jù)一個(gè)對(duì)象聊倔,獲取該對(duì)象的類
jclass GetSuperClass(jclass obj) 獲取一個(gè)類的父類
其對(duì)應(yīng)的java代碼的方式是:
NativeHelper.printStaticHelloWorld();
注意無(wú)論GetStaticMethodID(env, clazz, name, sig)
和GetMethodID(env, clazz, name, sig)
晦毙,其第二個(gè)參數(shù)clazz都是類的class實(shí)例。