如有疑惑,请看之前几篇文章。
native 与 static native
java中
public native String helloJni(); public native static String helloJniStatic();
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)
区别在于第二个参数是jobject还是jclass,和java中static方法属于类而不属于对象一样,static 的native方法属于类,所以第二个参数是jclass而不是jobject。
jobject获取jclass
jclass cls = env->GetObjectClass(jobj);
注意:这里获取到的cls是已有对象的cls。
jclass获取jobject
jmethodID cid = env->GetMethodID(cls, "<init>", "()V");jobject jobj = env->NewObject(cls, cid);
注意:这里获取到的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); jfieldID jfid = env->GetStaticFieldID(cls, "age", "I"); jint jage = env->GetStaticIntField(cls, jfid); jage += 10; env->SetStaticIntField(cls,jfid, jage); return env->NewStringUTF("hello jni"); }
通过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){ jclsToJobj(env, cls); jfieldID jfid = env->GetStaticFieldID(cls, "age", "I"); jint jage = env->GetStaticIntField(cls, jfid); jage += 10; env->SetStaticIntField(cls,jfid, jage); return env->NewStringUTF("hello jni static");};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
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])
输出结果:
09-26 16:29:27.634 3969-3969/? I/MainActivity-: age修改前: 1009-26 16:29:27.634 3969-3969/? I/MainActivity-: helloJni->hello jni09-26 16:29:27.634 3969-3969/? I/MainActivity-: age修改后: 2009-26 16:29:27.634 3969-3969/? I/MainActivity-: ------------------------------------------09-26 16:29:27.634 3969-3969/? I/MainActivity-: age修改前: 2009-26 16:29:27.634 3969-3969/? I/MainActivity-: courses修改前: 语文09-26 16:29:27.634 3969-3969/? I/MainActivity-: age修改后: 3009-26 16:29:27.634 3969-3969/? I/MainActivity-: courses修改后: 语文
可见通过jclass获取的jobject是一个新的对象,并不会改变已有对象的值。