- 1、本文档共33页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
深入理解JNI
数据类型转换 为了验证刚儿说的那句话,我们还是以MediaScanner为例,看看这个类里面的processFile这个函数: //java层processFile三个参数如下 private native void processFile(String path, String mimeType, MediaScannerClient client); //JNI层对应函数,左后3个参数与processFile的参数对应 static void android_media_MediaScanner_processFile( JNIEnv *env, jobject thiz, jstring path, jstring mimeType, jobject client) 从上面这段代码可以发现: Java的String类型对应JNI层为jString类型 Java的MediaScannerClient类型在JNI层对应为jobject 这里看到,java中的processFile有3个参数,但JNI层对应的函数会有五个参数了?第一个参数JNIENV是什么?第二个参数jobject代表java层的MediaScanner对象,它表示实在哪个MediaScanner对象上调用processFile. JNIENV介绍 JNIENV是一个与线程相关的代表JNI环境的结构体,下图展示了JNIENV的内部结构 JNIEnv* 虚拟机内部数据结构 JNI内部函数指针1 JNI内部函数指针2 JNI内部函数指针3 JNI内部函数指针数组 JNI内部函数 JNI内部函数 JNI内部函数 从上图可知:JNIEnv实际提供了一些JNI系统函数,通过这些函数可以做到: 1.调用java的函数 2.操作jobect对象很多事情 其实你可以把它看作是native层调用java层的一个工具。 JNIENV介绍 JNIEnv有几个设计的原则:第一、JNIEnv指针被设计成了Thread Local Storage(TLS线程本地存储)变量,也就 是说每一个Thread, JNIEnv变量都有独立的对象。这样做的原因主要 是考虑到: 由于JVM要运行在多个平台(除了主流的Windows,Linux等平台),JNI内部实现很多要依赖到TLS, 为了减少对TLS的依赖,所有TLS based的 数据都会存放于JNIEnv中。这样相当于只依赖一个TLS based的变量JNIEnv。由于JNIEnv指针是TLS的,所以你不能把Thead#1使用的JNIEnv给Thread#2使用。 第二、JNIEnv中定义了一组函数指针,c/c++ Native程序是通过这些函数指针操纵Java数据。这样设计的好处是:你的c/c++ 程序不需要依赖任何函数库,或者DLL。由于JVM可能由不同的厂商实现,不同厂商有自己不同的JNI实现,如果要求这些厂商暴露约定好的一些头文件和库,这不是灵活的设计。而且使用函数指针表的另外一个好处是: JVM可以根据启动参数动态替换JNI实现。比如:类似于C库,JNI实现为了性能起见,并没有对调用者传入的参数进行检查。但是在调试阶段,也许这种检查是很必要的,帮助你尽早发现BUG。例如如果你使用IBM JDK,你可以指定JVM参数–Xcheck:jni,告诉JVM使用带检查的JNI实现。 JNIENV介绍 通过前面对JNIEnv设计原则讲解可以看出,JNIEnv是一个与线程相关的变量,也就是说,线程A有一个JNIEnv,线程B也有一个JNIENV,他们彼此之间相互独立。同时JNIEnv是native函数转换成JNI函数由虚拟机传进来的。 那么,现在有一种情况,当后台程序收到一个网络消息,而这个过程需要由native层主动调用java层函数时,JNIEnv从何而来?根据前面的介绍可知,我们不能再线程A里用线程B的JNIEnv结构体,也不能保存另外的一个线程JNIEnv到后台程序里。这又怎么
文档评论(0)