题目有点大,呵呵。前边是高老师的东东,后边是我的小实践。话说当?/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)