JNI开发总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/good123day/article/details/85332832

jni接口实现由两种方式:
1. 通过javah,获取一组带签名函数,然后实现这些函数,官方推荐。
2. 系统中调用System.loadLibrary函数时,如果该函数"JNI_OnLoad"存在,则调用它。JNI_OnLoad可以和JNIEnv的registerNatives函数结合起来,实现动态的函数替换
    动态替换的方法,不用每个函数都写包名和类名,仅需要函数声明。
    通过JNINativeMethod结构体{函数名称,函数java签名, 函数指针},把所有接口列出;
    通过clazz = (*env)->FindClass(env, kClassName)找到要注册的类;
    通过(*env)->RegisterNatives(env, clazz,gMethods, sizeof(gMethods)/sizeof(gMethods[0]))注册函数,将本地方法和java类关联。
    

void JNI_OnUnload(JavaVM *vm, void *reserved);
作用:
1. 加载本地库的时被调用(例如,通过System.loadLibrary)
2. 必须返回本地库所需的JNI版本,JNI_VERSION_1_4,JNI_VERSION_1_6
3. 用于保存JavaVM

第一个参数是JavaVM,它是虚拟机在JNI层的代表,整个进程中javaVM只有一个

如果另一个线程需要访问Java VM,先调用GetEnv()方法获取JNI接口指针(JNIEnv)仅在当前线程中有效(不能多个线程共享一个JNIEnv)。之后调用AttachCurrentThread()
将自己附加到VM。一旦连接到虚拟机,本地线程就像在本地方法内运行的普通Java线程一样工作。
本地线程保持连接到VM直到它调用DetachCurrentThread()分离自己,释放对应的资源。


JNI常见变量:
JavaVM
JNIEnv
jclass
jobject
jfieldID
jmethodID
jcontext

JNI常见函数:
获取虚拟机:(*vm)->GetEnv(vm, (void **) env, JNI_VERSION_1_6);
jar中查找类:jclass ClassName = (*env)->FindClass(env, "com/ajdx/multi/jniapi/JarClassName");
获取类:jclass ClassName = (*env)->GetObjectClass(env, jobject);
获取函数:jmethodID getInstanceID = (*env)->GetStaticMethodID(env, ClassName, "getInstance","()Lcom/ajdx/multi/jniapi/JarClassName;");
                     jmethodID methodID = (*env)->GetMethodID(env, ClassName, "GenRandom", "(I[B)I");
函数调用:(*env)->CallStaticObjectMethod(env, ClassName, getInstanceID);
                    (*env)->CallIntMethod(env, Jobject, methodID,....);
获取类字段:(*env)->GetFieldID(env, jclassName, "fieldName", "Ljava/lang/Object;");
创建全局引用:(*env)->NewGlobalRef(env, jobjectName);//任何jobect对象都可以使用NewGlobalRef,创建全局引用,注意多线程时需要注意该函数。

猜你喜欢

转载自blog.csdn.net/good123day/article/details/85332832