题目有点大,呵呵。前边是高老师的东东,后边是我的小实践。话说当æ—?/p>
Android
还是
1.5
的ã€?/p>
Android JNI
知识简ä»?/p>
Java Native Interface (JNI)
标准æ˜?/p>
java
平台的一部分,它允许
Java
代码和其他语言写的代码
进行交互ã€?/p>
JNI
是本地编程接口,它使得在
Java
虚拟æœ?/p>
(VM)
内部运行çš?/p>
Java
代码能够
与用其它编程语言
(
�/p>
C
�/p>
C++
和汇编语言
)
编写的应用程序和库进行交互操作ã€?/p>
1.
从如何载å…?/p>
.so
档案谈起
由于
Android
的应用层的类都是ä»?/p>
Java
写的,这äº?/p>
Java
类编译为
Dex
型式çš?/p>
Bytecode
之后,必须靠
Dalvik
虚拟æœ?/p>
(VM:
Virtual
Machine)
来执行ã€?/p>
VM
�/p>
Android
平台里,扮演å¾?/p>
重要的角色ã€?/p>
此外,在执行
Java
类的过程中,如果
Java
类需要与
C
组件沟通时ï¼?/p>
VM
就会去载å…?/p>
C
组件,然后让
Java
的函数顺利地调用åˆ?/p>
C
组件的函数。此时,
VM
扮演着桥梁的角色,è®?/p>
Java
�/p>
C
组件能通过标准çš?/p>
JNI
介面而相互沟通ã€?/p>
应用层的
Java
类是在虚拟机
(VM: Vitual Machine)
上执行的ï¼?/p>
�/p>
C
件不是在
VM
上执行,
那么
Java
程式又如何要æ±?/p>
VM
去载å…?/p>
(Load)
所指定çš?/p>
C
组件å‘?/p>
?
可使用下述指令:
System.loadLibrary(*.so
的档案名
);
例如ï¼?/p>
Android
框架里所提供çš?/p>
MediaPlayer.java
类,含指令:
public class MediaPlayer{
static {
System.loadLibrary("media_jni");
}
}
这要æ±?/p>
VM
去载å…?/p>
Android
çš?/p>
/system/lib/libmedia_jni.so
档案。载å…?/p>
*.so
之后ï¼?/p>
Java
ç±?/p>
�/p>
*.so
档案就汇合起来,一起执行了ã€?/p>
2.
如何撰写
*.so
的入口函æ•?/p>
---- JNI_OnLoad()
�/p>
JNI_OnUnload()
函数的用é€?/p>
å½?/p>
Android
çš?/p>
VM(Virtual Machine)
执行åˆ?/p>
System.loadLibrary()
函数时,
首先会去执行
C
组件
里的
JNI_OnLoad()
函数。它的用途有二:
(1)
告诉
VM
æ?/p>
C
组件使用那一ä¸?/p>
JNI
版本。如果你çš?/p>
*.so
档没有提ä¾?/p>
JNI_OnLoad()
函数ï¼?/p>
VM
会默认该
*.so
档是使用最老的
JNI
1.1
版本。由于新版的
JNI
做了许多扩充,如果需è¦?/p>
使用
JNI
的新版功能,
例如
JNI 1.4
çš?/p>
java.nio.ByteBuffer,
就必须藉ç”?/p>
JNI_OnLoad()
函数来告
�/p>
VM
�/p>
(2)
由于
VM
执行åˆ?/p>
System.loadLibrary()
函数时,就会立即先呼å�?/p>
JNI_OnLoad()
,所ä»?/p>
C
ç»?/p>
件的开发者可以藉ç”?/p>
JNI_OnLoad()
来进è¡?/p>
C
组件内的初期值之设定
(Initialization)
�/p>
例如,在
Android
çš?/p>
/system/lib/libmedia_jni.so
档案里,就提供了
JNI_OnLoad()
函数,其ç¨?/p>
式码片段为:
//#define LOG_NDEBUG 0
#define LOG_TAG "MediaPlayer-JNI"
jint JNI_OnLoad(JavaVM* vm, void* reserved)