Java静态和非静态调用native区别

[TOC]

Java静态和非静态调用native区别

直接先上结论

java申明native方法时,native方法修饰分为static和非static

两个区别在于,对于jobject *obj

  • 静态的其实是个Class的对象,类型是java端对应的类,super类型是java/lang/Class

  • 非静态是java端类对象实例,super类型是对应的class对象

如下:

//静态调用
[class xxx.JniCam, class java.lang.Class]

//实例调用
[xxx.JniCam@346a4f, class xxx.JniCam]

测试

  • native端实现

static void GeneralCallback(JNIEnv *env, jint type, jobject *objects, int size) {

    jclass lds = static_cast<jclass>(gObject);

    jclass base = env->FindClass("java/lang/Object");

    jobjectArray array = env->NewObjectArray(size, base, base);

    for (int i = 0; i < size; i++) {

        env->SetObjectArrayElement(array, i, objects[i]);

    }

    {

        pthread_mutex_lock(&gMutex);

        jmethodID jniCallback = env->GetStaticMethodID(lds, "JniCallback",

                                                        "(I[Ljava/lang/Object;)V");

        if (jniCallback != nullptr)

            env->CallStaticVoidMethod(lds, jniCallback, type, array);

        pthread_mutex_unlock(&gMutex);

    }

}

void test(JNIEnv *env, jobject obj, int type) {

    jobject objects[2];

    objects[0] = obj;

    objects[1] = env->GetObjectClass(obj);

    GeneralCallback(env, type, objects, 2);

}

JNIEXPORT void JNICALL

Java_xxx_JniCam_init(JNIEnv *env, jobject obj) {

    gObject = env->NewGlobalRef(obj);

}

JNIEXPORT void JNICALL Java_xxx_JniCam_test(JNIEnv *env, jobject instance){

    test(env, instance, 100);

}

JNIEXPORT void JNICALL Java_xxx_JniCam_testStatic(JNIEnv *env, jobject instance){

    test(env, instance, 101);

}

  • java端申明

  public static native void init();

  public static native void testStatic();

  public native void test();

  public static void JniCallback(int type, Object... info){

        Logger.INSTANCE().i("JniCallback", type, info);

    }

  • java端调用

  JniCam.init();

  JniCam.testStatic();

  new JniCam().test();

  • 回调结果

JniCallback 101 [class xxx.JniCam, class java.lang.Class]

JniCallback 100 [xxx.JniCam@346a4f, class xxx.JniCam]

结语

  1. 总结

以上代码是为了结构清晰,只展示了关键的测试代码,具体结构构建,网上随便搜一个初始教程"hello_world"就可以了,涉及到知识为:

  • Jni静态和动态注册,本例使用静态注册的方式
  • Jni引用,引用分为局部、全局和弱全局引用
  • Jni静态和非静态回调,本例回调的是java端的静态方法,其实了解Java反射的话,对这块会很好理解
  • 方法签名类型定义,方法有重载,所以需要签名(也就是参数、返回值)区别一下,这边关于签名的类型定义,了解Smali方面的知识的话,会很容易理解
  1. 注意

在上面初始化时, 创建了一个全局引用 gObject, 记得是需要在最后(例如:JNI_OnUnload())释放

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容