如有疑惑,请看之前几篇文章。
native 与 static native
java中
public native String
helloJni();
public native static String
helloJniStatic();
12
JNI中
JNIEXPORT jstring JNICALL Jav
a_com_test_git_jnidemo_JniUtil_JniDemo_helloJni
(JNIEnv *, jobject)
JNIEXPORT jstring JNICALL Jav
a_com_test_git_jnidemo_JniUtil_JniDemo_helloJniStatic
(JNIEnv *, jclass)
12345
区别在于第二个参数是jobject还是jclass,和java中static方法属于类而不属于对象一样,static 的native方法属于类,所以第二个参数是jclass而不是jobject。
jobject获取jclass
j
class cls = env->GetObjectClass(jobj);
1
注意:这里获取到的cls是已有对象的cls。
jclass获取jobject
jmethodID cid = env->GetMethodID(cls,
"<init>",
"()V");
j
object jobj = env->NewObject(cls, cid);
12
注意:这里获取到的jobj已经是一个新的对象。
下面看一组对比Demo
通过jobject获取jclass,并修改对象中的age字段
JNIEXPORT jstring JNICALL Java_com_test_git_jnidemo_JniUtil_JniDemo_helloJni
(JNIEnv *env, j
object jobj){
j
class 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");
}
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){
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");
};
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是一个新的对象,并不会改变已有对象的值。