本文基于Hello JNI
如有疑惑,请看之前几篇文章。
public native String helloJni();
public native static String helloJniStatic();
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。
jclass cls = env->GetObjectClass(jobj);
注意:这里获取到的cls是已有对象的cls。
jmethodID cid = env->GetMethodID(cls, "<init>", "()V");
jobject jobj = env->NewObject(cls, cid);
注意:这里获取到的jobj已经是一个新的对象。
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");
}
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");
};
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修改前: 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修改后: 语文
可见通过jclass获取的jobject是一个新的对象,并不会改变已有对象的值。