Android JNI之动态注册(android studio)
来源:互联网 发布:世界历史数据库 编辑:程序博客网 时间:2024/06/10 15:59
故事得从这里开始-静态注册
没有对比,就没有伤害。静态注册自出生以来,就非议颇多。繁琐的过程(javah生成头文件),每增加一个接口,渣握h一下。长长长的函数名称,一个详细的身份证明。运行效率较低,第一次进行交流的时候,根据详细的身份去jni中查找对应身份的人,这个难度比较大,一个一个去对比,运气好,一次匹配就建立了关系,如果,假如说如果,等到最后,黄花菜都凉了。艰难的时候,到了要放弃的时候,man是时候登场了,动态注册,对,就是他。JNI中有一个函数映射表,注册给Jave虚拟机,一见钟情,交流就是这么顺畅。
动态注册,画了几个圈
规则,还是要有的。早早建立数据库,交流一触即发。
一。入口 JNI_OnLoad 方法
System.loadLibrary加载完 JNI 动态库之后,调用JNI_OnLoad函数,开始动态注册。这里就是报名注册的地方,地方不能找错,你报个警抓小偷,非要打个119,我也很悲伤,但无能为力。注意:一个.so只能存在一个onload方法。
二。重头戏 RegisterNatives 方法
在 JNI 帝国中,不得不介绍下 JNIEnv*,JVM代言人,掌握java生杀大权,java环境变量指针,是一个包含了JVM接口的结构,它包含了与JVM进行交互以及与Java对象协同工作所必需的函数。而 RegisterNatives 只是其中的一颗棋子,登记员。但只有通过他,你才能进入函数映射表。函数映射表?不急,我们慢慢来,一步一步剥离他的心。在 jni.h 帝国中,描述有这么一段:
typedef struct { const char* name; //Java中函数的名字 const char* signature; //描述了函数的参数和返回值 void* fnPtr; //函数指针,指向我们调用别人家c++的封装 JNI 函数方法} JNINativeMethod;
这就是函数映射表的数据结构,注释加上,似乎也没什么需要解释的了,至于繁琐的源代码解析,这个结构又是怎么被使用,脑补,脑补。咳咳咳,回归正题,重头戏 RegisterNatives,这是一部宫廷史诗剧,精心的布局,宏大的场面。这么说吧,演员甲乙丙,就三个,共同出演一部不是你死就是我死的故事结局。剧本中记载了这么一段:
/** * 向JNI环境注册一个本地方法 * @param clazz 包含本地方法的Java类 * @param methods 本地方法描述数组 * @param nMethods 本地方法个数 * @return 成功返回0,否则注册失败 */jint RegisterNatives(jclass clazz, const JNINativeMethod *methods, jint nMethods);
不知不觉,后知后觉,一个注释完成了解析。简单点,说话的方式简单点。该配合你演出的我演视而不见。这个登记员的描述,大体如此了,如有更多需求,请自行研究。
三。结束 JNI_OnUnload 方法
出来混的迟早都是要还的,庞大的 JNI 帝国也有结束的那一天。当VM释放该组件时会调用 JNI_OnUnload 方法,曾经拥有的,比如说对象啊,通通在这里回归大地,化作春泥更护花。 当然也可以选择放弃,这个方法甩在一边,那么毒蘑菇总有一天会茁壮成长的,慢慢慢慢,然后boom。优化,是你我的一个可选项。
四。奇迹见证时刻
不得不说,这个时刻,我特别激动。花儿,为什么这么红?略微贴下代码,稍显细节:
static const char *jniClassName = "net/mapout/jni/JNILoader";static JNINativeMethod methods[] = { {"sayHello", "()Ljava/lang/String;", (void*)jniSayHello},};static int registerNatives(JNIEnv* env) { jclass clazz = env->FindClass(jniClassName); if (clazz == NULL) return JNI_FALSE; jint methodSize = sizeof(methods) / sizeof(methods[0]); if ( env->RegisterNatives(clazz, methods, methodSize) < 0 ) return JNI_FALSE; return JNI_TRUE;}JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { JNIEnv* env = NULL; jint result = -1; if (vm->GetEnv((void **)&env, JNI_VERSION_1_6) != JNI_OK) return JNI_ERR; //注册方法 if (!registerNatives(env)) return JNI_ERR; result = JNI_VERSION_1_6; return result;}JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) { JNIEnv *env = nullptr; jint ret = vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6); if (ret != JNI_OK) { return ; } //回收二手女朋友,回收... 嘿嘿嘿}
一目了然,我们所需要维护的就是methods这个数组了,剩下的都是复制粘贴。稍微来个对比:
/** * 动态注册。命名简洁,清晰明了 */jstring jniSayHello(JNIEnv *env, jobject obj){ return str2jstring( env, sayHello() );}/** * 静态注册。噗噗噗,一口老血喷涌而出 */JNIEXPORT jstring JNICALL Java_net_mapout_jni_JNILoader_sayHello (JNIEnv *env, jclass jclass){ return str2jstring( env, sayHello() );}
又是一个注释。代码,没有一个注释不能说清楚的,如果有,那就请用两个注释。说个细节,这里函数都有2个参数,一个 JNIEnv * 已经解释过了,还一个jobject。稍微讲一下,native方法如果没有static,那么就是类的实例,如果武装了static,进化加强,变为了类的class对象的实例。动态注册,就是这么回事,是时候展示实力的时候了。
- Android JNI之动态注册(android studio)
- Android Studio jni动态注册步骤
- Android Studio Jni开发(三)Native方法动态注册
- Android JNI之静态注册(android studio)
- Android 动态注册JNI
- Android: JNI动态注册
- Android JNI动态注册
- Android 动态注册JNI
- Android JNI使用方法(“动态注册”)
- Android JNI使用方法(“动态注册”)
- Android JNI 动态注册方法(JNI_OnLoad)
- android 动态注册Jni函数
- Android JNI的动态注册
- Android 动态注册JNI函数
- Android 动态注册JNI函数
- Android Studio NDK 入门教程(8)--JNI动态注册本地方法
- Android jni 静态注册 和动态注册
- Android JNI学习之动态注册native函数
- MesaSQLite 注册码
- object file (xx.a(xx.o)) was built for newer iOS version (10.3) than being linked (10.2)
- 机器学习【周志华】课后习题2.5证明
- 算法竞赛入门经典-习题3-2 分子量(Molar Mass, ACM/ICPC Seoul 2007, UVa1586)
- RadioButton背景色选择器和文字的选择器
- Android JNI之动态注册(android studio)
- Glide使用造成OOM解决方案
- Hystrix使用入门手册(中文)
- [练习] LCA练习1(最基础)
- 归并排序
- 解决css3动画效果在360兼容模式跟猎豹浏览器下不兼容
- SQL存储过程的优点、创建、互相调用与调试
- FMS4.5/AMS5重置管理员密码方法
- 2. Add Two Numbers