欢迎来到人人文库网! | 帮助中心 人人文库renrendoc.com美如初恋!
人人文库网
首页 人人文库网 > 资源分类 > DOC文档下载

23JNI与Android VM之关系.doc

  • 资源大小:63.00KB        全文页数:5页
  • 资源格式: DOC        下载权限:游客/注册会员/VIP会员    下载费用:3
游客快捷下载 游客一键下载
会员登录下载
下载资源需要3

邮箱/手机号:
您支付成功后,系统会自动为您创建此邮箱/手机号的账号,密码跟您输入的邮箱/手机号一致,以方便您下次登录下载和查看订单。注:支付完成后需要自己下载文件,并不会自动发送文件哦!

支付方式: 微信支付    支付宝   
验证码:   换一换

友情提示
2、本站资源不支持迅雷下载,请使用浏览器直接下载(不支持QQ浏览器)
3、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰   

23JNI与Android VM之关系.doc

23JNI与ANDROIDVM之关系1从如何载入SO档案谈起由于ANDROID的应用层级类别都是以JAVA撰写的,这些JAVA类别转译为DEX型式的BYTECODE之后,必须仰赖DALVIK虚拟机器VMVIRTUALMACHINE来执行之。VM在ANDROID平台里,扮演很重要的角色。此外,在执行JAVA类别的过程中,如果JAVA类别需要与C组件沟通时,VM就会去加载C组件,然后让JAVA的函数顺利地呼叫到C组件的函数。此时,VM扮演着桥梁的角色,让JAVA与C组件能透过标准的JNI接口而相互沟通。应用层级的JAVA类别是在虚拟机器VMVITUALMACHINE上执行的,而C组件不是在VM上执行,那么JAVA程序又如何要求VM去加载LOAD所指定的C组件呢可使用下述指令SYSTEMLOADLIBRARYSO的檔名;例如,在上一节的范例里的NATIVEJNIADDER类别,其程序代码看看ANDROID框架里所提供的MEDIAPLAYERJAVA类别,内含指令PUBLICCLASSMEDIAPLAYER{STATIC{SYSTEMLOADLIBRARYMEDIA_JNI;}}这要求VM去加载ANDROID的/SYSTEM/LIB/LIBMEDIA_JNISO档案。载入SO档之后,JAVA类别与SO档就汇合起来,一起执行了。2如何撰写SO的入口函数JNI_ONLOAD与JNI_ONUNLOAD函数之用途当VM执行到SYSTEMLOADLIBRARY函数时,首先会去执行C组件里的JNI_ONLOAD函数。它的用途有二1告诉VM此C组件使用那一个JNI版本。如果你的SO文件没有提供JNI_ONLOAD函数,VM会默认该SO檔是使用最老的JNI11版本。由于新版的JNI做了许多扩充,如果需要使用JNI的新版功能,例如JNI14的JAVANIOBYTEBUFFER,就必须藉由JNI_ONLOAD函数来告知VM。2由于VM执行到SYSTEMLOADLIBRARY函数时,就会立即先呼叫JNI_ONLOAD,所以C组件的开发者可以藉由JNI_ONLOAD来进行C组件内的初期值之设定INITIALIZATION。例如,在ANDROID的/SYSTEM/LIB/LIBMEDIA_JNISO档案里,就提供了JNI_ONLOAD函数,其程序代码片段为//DEFINELOG_NDEBUG0DEFINELOG_TAGMEDIAPLAYERJNIJINTJNI_ONLOADJAVAVMVM,VOIDRESERVED{JNIENVENVNULL;JINTRESULT1;IFVMGETENVVOIDENV,JNI_VERSION_1_4JNI_OK{LOGEERRORGETENVFAILED\N;GOTOBAIL;}ASSERTENVNULL;IFREGISTER_ANDROID_MEDIA_MEDIAPLAYERENV0{LOGEERRORMEDIAPLAYERNATIVEREGISTRATIONFAILED\N;GOTOBAIL;}IFREGISTER_ANDROID_MEDIA_MEDIARECORDERENV0{LOGEERRORMEDIARECORDERNATIVEREGISTRATIONFAILED\N;GOTOBAIL;}IFREGISTER_ANDROID_MEDIA_MEDIASCANNERENV0{LOGEERRORMEDIASCANNERNATIVEREGISTRATIONFAILED\N;GOTOBAIL;}IFREGISTER_ANDROID_MEDIA_MEDIAMETADATARETRIEVERENV0{LOGEERRORMEDIAMETADATARETRIEVERNATIVEREGISTRATIONFAILED\N;GOTOBAIL;}/SUCCESSRETURNVALIDVERSIONNUMBER/RESULTJNI_VERSION_1_4;BAILRETURNRESULT;}//KTHXBYE此函数回传JNI_VERSION_1_4值给VM,于是VM知道了其所使用的JNI版本了。此外,它也做了一些初期的动作可呼叫任何本地函数,例如指令IFREGISTER_ANDROID_MEDIA_MEDIAPLAYERENV0{LOGEERRORMEDIAPLAYERNATIVEREGISTRATIONFAILED\N;GOTOBAIL;}就将此组件提供的各个本地函数NATIVEFUNCTION登记到VM里,以便能加快后续呼叫本地函数之效率。JNI_ONUNLOAD函数与JNI_ONLOAD相对应的。在加载C组件时会立即呼叫JNI_ONLOAD来进行组件内的初期动作;而当VM释放该C组件时,则会呼叫JNI_ONUNLOAD函数来进行善后清除动作。当VM呼叫JNI_ONLOAD或JNI_UNLOAD函数时,都会将VM的指标POINTER传递给它们,其参数如下JINTJNI_ONLOADJAVAVMVM,VOIDRESERVED{}JINTJNI_ONUNLOADJAVAVMVM,VOIDRESERVED{}在JNI_ONLOAD函数里,就透过VM之指标而取得JNIENV之指标值,并存入ENV指针变量里,如下述指令JINTJNI_ONLOADJAVAVMVM,VOIDRESERVED{JNIENVENVNULL;JINTRESULT1;IFVMGETENVVOIDENV,JNI_VERSION_1_4JNI_OK{LOGEERRORGETENVFAILED\N;GOTOBAIL;}}由于VM通常是多执行绪MULTITHREADING的执行环境。每一个执行绪在呼叫JNI_ONLOAD时,所传递进来的JNIENV指标值都是不同的。为了配合这种多执行绪的环境,C组件开发者在撰写本地函数时,可藉由JNIENV指标值之不同而避免执行绪的数据冲突问题,才能确保所写的本地函数能安全地在ANDROID的多执行绪VM里安全地执行。基于这个理由,当在呼叫C组件的函数时,都会将JNIENV指标值传递给它,如下JINTJNI_ONLOADJAVAVMVM,VOIDRESERVED{JNIENVENVNULL;IFREGISTER_ANDROID_MEDIA_MEDIAPLAYERENV0{}}这JNI_ONLOAD呼叫REGISTER_ANDROID_MEDIA_MEDIAPLAYERENV函数时,就将ENV指标值传递过去。如此,在REGISTER_ANDROID_MEDIA_MEDIAPLAYER函数就能藉由该指标值而区别不同的执行绪,以便化解数据冲突的问题。例如,在REGISTER_ANDROID_MEDIA_MEDIAPLAYER函数里,可撰写下述指令IFENVMONITORENTERENV,OBJJNI_OK{}查看是否已经有其它执行绪进入此对象,如果没有,此执行绪就进入该对象里执行了。还有,也可撰写下述指令IFENVMONITOREXITENV,OBJJNI_OK{}查看是否此执行绪正在此对象内执行,如果是,此执行绪就会立即离开。3REGISTERNATIVEMETHODS函数之用途应用层级的JAVA类别透过VM而呼叫到本地函数。一般是仰赖VM去寻找SO里的本地函数。如果需要连续呼叫很多次,每次都需要寻找一遍,会多花许多时间。此时,组件开发者可以自行将本地函数向VM进行登记。例如,在ANDROID的/SYSTEM/LIB/LIBMEDIA_JNISO档案里的程序代码片段如下//DEFINELOG_NDEBUG0DEFINELOG_TAGMEDIAPLAYERJNISTATICJNINATIVEMETHODGMETHODS{{SETDATASOURCE,LJAVA/LANG/STRING;V,VOIDANDROID_MEDIA_MEDIAPLAYER_SETDATASOURCE},{SETDATASOURCE,LJAVA/IO/FILEDESCRIPTOR;JJV,VOIDANDROID_MEDIA_MEDIAPLAYER_SETDATASOURCEFD},{PREPARE,V,VOIDANDROID_MEDIA_MEDIAPLAYER_PREPARE},{PREPAREASYNC,V,VOIDANDROID_MEDIA_MEDIAPLAYER_PREPAREASYNC},{_START,V,VOIDANDROID_MEDIA_MEDIAPLAYER_START},{_STOP,V,VOIDANDROID_MEDIA_MEDIAPLAYER_STOP},{GETVIDEOWIDTH,I,VOIDANDROID_MEDIA_MEDIAPLAYER_GETVIDEOWIDTH},{GETVIDEOHEIGHT,I,VOIDANDROID_MEDIA_MEDIAPLAYER_GETVIDEOHEIGHT},{SEEKTO,IV,VOIDANDROID_MEDIA_MEDIAPLAYER_SEEKTO},{_PAUSE,V,VOIDANDROID_MEDIA_MEDIAPLAYER_PAUSE},{ISPLAYING,Z,VOIDANDROID_MEDIA_MEDIAPLAYER_ISPLAYING},{GETCURRENTPOSITION,I,VOIDANDROID_MEDIA_MEDIAPLAYER_GETCURRENTPOSITION},{GETDURATION,I,VOIDANDROID_MEDIA_MEDIAPLAYER_GETDURATION},{_RELEASE,V,VOIDANDROID_MEDIA_MEDIAPLAYER_RELEASE},{_RESET,V,VOIDANDROID_MEDIA_MEDIAPLAYER_RESET},{SETAUDIOSTREAMTYPE,IV,VOIDANDROID_MEDIA_MEDIAPLAYER_SETAUDIOSTREAMTYPE},{SETLOOPING,ZV,VOIDANDROID_MEDIA_MEDIAPLAYER_SETLOOPING},{SETVOLUME,FFV,VOIDANDROID_MEDIA_MEDIAPLAYER_SETVOLUME},{GETFRAMEAT,ILANDROID/GRAPHICS/BITMAP;,VOIDANDROID_MEDIA_MEDIAPLAYER_GETFRAMEAT},{NATIVE_SETUP,LJAVA/LANG/OBJECT;V,VOIDANDROID_MEDIA_MEDIAPLAYER_NATIVE_SETUP},{NATIVE_FINALIZE,V,VOIDANDROID_MEDIA_MEDIAPLAYER_NATIVE_FINALIZE},};STATICINTREGISTER_ANDROID_MEDIA_MEDIAPLAYERJNIENVENV{RETURNANDROIDRUNTIMEREGISTERNATIVEMETHODSENV,ANDROID/MEDIA/MEDIAPLAYER,GMETHODS,NELEMGMETHODS;}//JINTJNI_ONLOADJAVAVMVM,VOIDRESERVED{IFREGISTER_ANDROID_MEDIA_MEDIAPLAYERENV0{LOGEERRORMEDIAPLAYERNATIVEREGISTRATIONFAILED\N;GOTOBAIL;}}当VM载入LIBMEDIA_JNISO档案时,就呼叫JNI_ONLOAD函数。接着,JNI_ONLOAD呼叫REGISTER_ANDROID_MEDIA_MEDIAPLAYER函数。此时,就呼叫到ANDROIDRUNTIMEREGISTERNATIVEMETHODS函数,向VM即ANDROIDRUNTIME登记GMETHODS表格所含的本地函数了。简而言之,REGISTERNATIVEMETHODS函数的用途有二1更有效率去找到函数。2可在执行期间进行抽换。由于GMETHODS是一个名称,函数指针对照表,在程序执行时,可多次呼叫REGISTERNATIVEMETHODS函数来更换本地函数之指针,而达到弹性抽换本地函数之目的。

注意事项

本文(23JNI与Android VM之关系.doc)为本站会员(baixue100)主动上传,人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知人人文库网(发送邮件至[email protected]或直接QQ联系客服),我们立即给予删除!

温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。

关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服客服 - 联系我们

网站客服QQ:2846424093    人人文库上传用户QQ群:460291265   

[email protected] 2016-2018  renrendoc.com 网站版权所有   南天在线技术支持

经营许可证编号:苏ICP备12009002号-5