- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
23JNI与Android VM之关系.doc
23.JNI与Android VM之关系
1. 从*.so档案谈起
由于Android的应用层级类别都是以Java撰写的,这些Java类别转译为Dex型式的Bytecode之后,必须仰赖Dalvik虚拟机器(VM: Virtual Machine)来执行之。VM在Android平台里,扮演很重要的角色。
此外,在执行Java类别的过程中,如果Java类别需要与C组件沟通时,VM就会去加载C组件,然后让Java的函数顺利地呼叫到C组件的函数。此时,VM扮演着桥梁的角色,让Java与C组件能透过标准的JNI接口而相互沟通。
应用层级的Java类别是在虚拟机器(VM: Vitual Machine)上执行的,而C组件不是在VM上执行,那么Java程序又如何要求VM去加载(Load)所指定的C组件呢? 可使用下述指令:
System.loadLibrary(*.so的檔名);
?
例如,在上一节的范例里的NativeJniAdder类别,其程序代码:
看看 Android框架里所提供的MediaPlayer.java类别,内含指令:
public?class?MediaPlayer{????
????static?{
????????System.loadLibrary(media_jni);
????}
……..
}
这要求VM去加载Android的/system/lib/libmedia_jni.so档案。载入*.so档之后,Java类别与*.so档就汇合起来,一起执行了。
2.? 如何撰写*.so的入口函数
??? ---- JNI_OnLoad()与JNI_OnUnload()函数之用途
?
当VM执行到System.loadLibrary()函数时,首先会去执行C组件里的JNI_OnLoad()函数。它的用途有二:
1.?????? 告诉VM此C组件使用那一个JNI版本。如果你的*.so文件没有提供JNI_OnLoad()函数,VM会默认该*.so檔是使用最老的JNI 1.1版本。由于新版的JNI做了许多扩充,如果需要使用JNI的新版功能,例如JNI 1.4的 java.nio.ByteBuffer, 就必须藉由JNI_OnLoad()函数来告知VM。
2.?????? 由于VM执行到System.loadLibrary()函数时,就会立即先呼叫JNI_OnLoad(),所以C组件的开发者可以藉由JNI_OnLoad()来进行C组件内的初期值之设定(Initialization)。
例如,在Android的/system/lib/libmedia_jni.so档案里,就提供了JNI_OnLoad()函数,其程序代码片段为:
//#define?LOG_NDEBUG?0
#define?LOG_TAG?MediaPlayer-JNI
………
jint?JNI_OnLoad(JavaVM*?vm,?void*?reserved)
{
????JNIEnv*?env?=?NULL;
????jint?result?=?-1;
????if?(vm-GetEnv((void**)?env,?JNI_VERSION_1_4)?!=?JNI_OK)?{
????????LOGE(ERROR:?GetEnv?failed\n);
????????goto?bail;
????}
????assert(env?!=?NULL);
????if?(register_android_media_MediaPlayer(env)??0)?{
????????LOGE(ERROR:?MediaPlayer?native?registration?failed\n);
????????goto?bail;
????}
????if?(register_android_media_MediaRecorder(env)??0)?{
????????LOGE(ERROR:?MediaRecorder?native?registration?failed\n);
????????goto?bail;
????}
????if?(register_android_media_MediaScanner(env)??0)?{
????????LOGE(ERROR:?MediaScanner?native?registration?failed\n);
????????goto?bail;
????}
????if?(register_android_media_MediaMetadataRetriever(env)??0)?{
????????LOGE(ERROR:?MediaMetadat
文档评论(0)