native和static native区别

来源:互联网 发布:中心机房云计算 编辑:程序博客网 时间:2024/06/11 16:04

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

native 与 static native

java中

    public native String helloJni();    public native static String helloJniStatic();
  • 1
  • 2

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);
  • 1
  • 2
  • 3
  • 4
  • 5

区别在于第二个参数是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);
  • 1
  • 2

注意:这里获取到的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");  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

通过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");};
  • 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]);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

输出结果:

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修改后: 语文
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

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

原创粉丝点击