Android JNI开发入门之二
2010-12-18 08:04:03 来源:WEB开发网}
if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
LOGE("RegisterNatives failed for '%s'", className);
return JNI_FALSE;
}
return JNI_TRUE;
}
/*
* Register native methods for all classes we know about.
*
* returns JNI_TRUE on success.
*/
static int registerNatives(JNIEnv* env)
{
if (!registerNativeMethods(env, classPathName,
methods, sizeof(methods) / sizeof(methods[0]))) {
return JNI_FALSE;
}
return JNI_TRUE;
}
typedef union {
JNIEnv* env;
void* venv;
} UnionJNIEnvToVoid;
/* This function will be call when the library first be loaded */
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
UnionJNIEnvToVoid uenv;
JNIEnv* env = NULL;
LOGI("JNI_OnLoad!");
if (vm->GetEnv((void**)&uenv.venv, JNI_VERSION_1_4) != JNI_OK) {
LOGE("ERROR: GetEnv failed");
return -1;
}
env = uenv.env;;
if (registerNatives(env) != JNI_TRUE) {
LOGE("ERROR: registerNatives failed");
return -1;
}
return JNI_VERSION_1_4;
}
本例与上文《Android JNI开发入门之一》对比有如下几点不同需要注意:
1、C和C++实现共享库调用不同JNI API。前面已经提到Android系统JNI为C和C++提供了两套不同的API。请仔细对比NewStringUTF,GetEnv函数,就会发现JNI API不同。
2、C++版的helloworld共享库提供了函数映射表。前文《
Android JNI开发入门之一》也已经提到,JNI API为了避免丑陋的函数名,提供了方法向Java虚拟机注册函数映射表。这样当Java调用Native接口的时候,Java虚拟机就可以不用根据函数 名来决定调用哪个函数了,直接通过查询表格就可以找到需要调用的函数了。
3、我们注意到RegisterNatives第一个参数(C语言接口中是第二个参数)为调用该函数的Java类。这也和标准JNI函数名包含类名(包名和类名)的作用一样——声明那个Java类可以调用这个方法。
更多精彩
赞助商链接