Android JNI详述
2010-07-15 20:31:00 来源:WEB开发网jint JNI_OnLoad(JavaVM* vm, void* reserved) { }
jint JNI_OnUnload(JavaVM* vm, void* reserved){ }
在JNI_OnLoad() 函数里,就透过VM 之指标而取得JNIEnv 之指标值,并存入env 指标变数里,如下述指令:
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 ");
goto bail;
}
}
由于VM 通常是多执行绪(Multi-threading) 的执行环境。每一个执行绪在呼叫JNI_OnLoad() 时,所传递进来的JNIEnv 指标值都是不同的。为了配合这种多执行绪的环境,C 组件开发者在撰写本地函数时,可藉由JNIEnv 指标值之不同而避免执行绪的资料冲突问题,才能确保所写的本地函数能安全地在Android 的多执行绪VM 里安全地执行。基于这个理由,当在呼叫C 组件的函数时,都会将JNIEnv 指标值传递给它,如下:
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
JNIEnv* env = NULL;
if (register_android_media_MediaPlayer(env) < 0) {
}
}
这JNI_OnLoad() 呼叫register_android_media_MediaPlayer(env) 函数时,就将env 指标值传递过去。如此,在register_android_media_MediaPlayer() 函数就能藉由该指标值而区别不同的执行绪,以便化解资料冲突的问题。
例如,在register_android_media_MediaPlayer() 函数里,可撰写下述指令:
if ((*env)->MonitorEnter(env, obj) != JNI_OK) {
}
查看是否已经有其他执行绪进入此物件,如果没有,此执行绪就进入该物件里执行了。还有,也可撰写下述指令:
if ((*env)->MonitorExit(env, obj) != JNI_OK) {
}
查看是否此执行绪正在此物件内执行,如果是,此执行绪就会立即离开。
3.registerNativeMethods() 函数的用途
应用层级的Java 类别透过VM 而呼叫到本地函数。一般是仰赖VM 去寻找*.so 里的本地函数。如果需要连续呼叫很多次,每次都需要寻找一遍,会多花许多时间。此时,组件开发者可以自行将本地函数向VM 进行登记。例如,在Android
更多精彩
赞助商链接