native和static native区别

xiaoxiao2021-02-28  22

如有疑惑,请看之前几篇文章。

native 与 static native

java中

public native String helloJni(); public native static String helloJniStatic(); 12

JNI中

JNIEXPORT jstring JNICALL Java_com_test_git_jnidemo_JniUtil_JniDemo_helloJni (JNIEnv *, jobject); JNIEXPORT jstring JNICALL Java_com_test_git_jnidemo_JniUtil_JniDemo_helloJniStatic (JNIEnv *, jclass); 12345

区别在于第二个参数是jobject还是jclass,和java中static方法属于类而不属于对象一样,static 的native方法属于类,所以第二个参数是jclass而不是jobject。

jobject获取jclass

jclass cls = env->GetObjectClass(jobj); 1

注意:这里获取到的cls是已有对象的cls。

jclass获取jobject

jmethodID cid = env->GetMethodID(cls, "<init>", "()V"); jobject jobj = env->NewObject(cls, cid); 12

注意:这里获取到的jobj已经是一个新的对象。

下面看一组对比Demo

通过jobject获取jclass,并修改对象中的age字段

JNIEXPORT jstring JNICALL Java_com_test_git_jnidemo_JniUtil_JniDemo_helloJni (JNIEnv *env, jobject jobj){ jclass cls = env->GetObjectClass(jobj); //2.获取age的jfieldID 注意用GetStaticFieldID方法 jfieldID jfid = env->GetStaticFieldID(cls, "age", "I"); //3.通过jfid获取age的属性值,注意用GetStaticIntField jint jage = env->GetStaticIntField(cls, jfid); jage += 10; //4.修改age的属性值,注意用GetStaticIntField env->SetStaticIntField(cls,jfid, jage); return env->NewStringUTF("hello jni"); } 123456789101112

通过jclass获取jobject,然后修改courses数组中第一个元素的值

JNIEXPORT void jclsToJobj(JNIEnv *env, jclass cls) { jmethodID cid = env->GetMethodID(cls, "<init>", "()V"); jobject jobj = env->NewObject(cls, cid); jfieldID fid = env->GetFieldID(cls, "courses", "[Ljava/lang/String;"); jobjectArray jarray = (jobjectArray) env->GetObjectField(jobj, fid); env->SetObjectArrayElement(jarray, 0, env->NewStringUTF("美术")); } jstring JNICALL Java_com_test_git_jnidemo_JniUtil_JniDemo_helloJniStatic (JNIEnv *env, jclass cls){ //jclass 转换成 jobject jclsToJobj(env, cls); //2.获取age的jfieldID 注意用GetStaticFieldID方法 jfieldID jfid = env->GetStaticFieldID(cls, "age", "I"); //3.通过jfid获取age的属性值,注意用GetStaticIntField jint jage = env->GetStaticIntField(cls, jfid); jage += 10; //4.修改age的属性值,注意用GetStaticIntField env->SetStaticIntField(cls,jfid, jage); return env->NewStringUTF("hello jni static"); }; 12345678910111213141516171819202122

MainActivity.java中运行两个方法

JniDemo jd = new JniDemo(); Log.i(TAG, "age修改前: " + jd.age); Log.i(TAG, "helloJni->" + jd.helloJni()); Log.i(TAG, "age修改后: " + jd.age); Log.i(TAG, "------------------------------------------"); Log.i(TAG, "age修改前: " + jd.age); Log.i(TAG, "courses修改前: " + jd.courses[0]); JniDemo.helloJniStatic(); Log.i(TAG, "age修改后: " + jd.age); Log.i(TAG, "courses修改后: " + jd.courses[0]); 123456789101112

输出结果:

09-26 16:29:27.634 3969-3969/? I/MainActivity-: age修改前: 10 09-26 16:29:27.634 3969-3969/? I/MainActivity-: helloJni->hello jni 09-26 16:29:27.634 3969-3969/? I/MainActivity-: age修改后: 20 09-26 16:29:27.634 3969-3969/? I/MainActivity-: ------------------------------------------ 09-26 16:29:27.634 3969-3969/? I/MainActivity-: age修改前: 20 09-26 16:29:27.634 3969-3969/? I/MainActivity-: courses修改前: 语文 09-26 16:29:27.634 3969-3969/? I/MainActivity-: age修改后: 30 09-26 16:29:27.634 3969-3969/? I/MainActivity-: courses修改后: 语文 12345678

可见通过jclass获取的jobject是一个新的对象,并不会改变已有对象的值。

转载请注明原文地址: https://www.6miu.com/read-1650243.html

最新回复(0)