- 1、本文档共16页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
Java Native Interface (JNI)标准是java 平台的一部分,它允许Java 代码和其他语言写的代码进行交互。
JNI 是本地编程接口,它使得在 Java 虚拟机 (VM) 内部运行的 Java 代码能够与用其它编程语言(如 C、C++
和汇编语言)编写的应用程序和库进行交互操作。
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 的档案名);
例如,Android 框架里所提供的MediaPlayer.java 类,含指令:
Java 代码:
1. public class MediaPlayer{
2. static {
3. System.loadLibrary(media_jni);
4. }
5.
6. }
7.
8.
复制代码
这要求VM 去载入Android 的/system/lib/libmedia_jni.so 档案。载入*.so 之后,Java 类与*.so 档案
就汇合起来,一起执行了。
2.如何撰写*.so 的入口函数
JNI_OnLoad()与JNI_OnUnload()函数的用途
当Android 的VM(Virtual Machine)执行到System.loadLibrary()函数时,首先会去执行C 组件里的
JNI_OnLoad()函数。它的用途有二:
(1)告诉VM 此C 组件使用那一个JNI 版本。如果你的*.so 档没有提供JNI_OnLoad()函数,VM 会默认该
*.so 档是使用最老的 JNI 1.1 版本。由于新版的JNI 做了许多扩充,如果需要使用JNI 的新版功能,例如
拓胜(广州)计算机技术服务有限公司
1/ 16
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()函数,其程式码片
段为:
Java 代码:
1.
2. //#define LOG_NDEBUG 0
3. #define LOG_TAG MediaPlayer-JNI
4.
5. jint JNI_OnLoad(JavaVM* vm, void* reserved){
6. JNIEnv* env = NULL;
7. jint result = -1;
8.
9. if (vm-GetEnv((void**) env, JNI_VERSION_1_4) != JNI_OK) {
10.LOGE(ERROR: GetEnv failed );
11.goto bail;
12.}
13.
14.assert(env != NULL);
文档评论(0)