您的位置:首页 > 移动开发 > Android开发

jni动态注册

2015-08-31 17:32 363 查看
当java层调用声明的native函数时,他会从对应的so库中寻找对应的c或c++函数,如果找不到就报错,如果找到就为这个函数和java声明的native建立一个联系,其实就是保存jni层函数的指针。以后再次调用java中声明的native函数时直接使用这个函数指针就可以了。

从这里可以看出静态方法就是根据函数名来建立java函数和jni函数之间的关联关系,而且要求jni层函数的名字必须遵循特定的格式。

动态注册:
用JNINativeMethod结构体保存java native函数和jni函数的一一对应关系
JNINativeMethod定义如下
typedef struct{
const char* name;//java中native函数的名字(不用携带包名)
const char* signature; //java函数的签名信息,用字符串表示
void* fnptr;//jni层对应函数的函数指针
}JNINativeMethod;

应该如何使用这个结构体呢?来看MediaScanner JNI层是如何做的

static JNINativeMethod gMethod[]={
....
{
“processFile” //java中native层函数的函数名
“(Ljava/lang/String;Ljava/lang/String;Landroid/media/MediaScannerClient;)V”,//processFile的签名信息
(void*) android_media_MediaScanner_processFile//jni层对应的函数指针
},
...
{
"native_init",
"()V";
(void*) android_media_MediaScanner_native_init
},
};

//注册JNINativeMethod数组
int register_android_media_MediaScanner(JNIEnv* env){
//"android/media/MediaScanner" 表明java中哪个类
return AndroidRuntime::registerNativeMethods( env, "android/media/MediaScanner" , gMethods ,NELEM(gMethods) );
}

动态注册函数调用时机
当java层通过System.loadLibrary加载完jni动态库后,紧接着会查找该库中一个叫JNI_OnLoad的函数,如果有就调用它,而动态注册的工作就是在这里完成的。

例:
jint JNI_OnLoad(JavaVm* vm, void* reserved){
JNIEnv* env=NULL;
jint result=-1;
if( vm->GetEnv( (void**) &env,JNI_VERSION_1_4 ) != JNI_OK ){
goto bail;
}

if( register_android_media_MediaScanner(env ) < 0 )
goto bail;
return JNI_VERSION_1_4 ; //必须返回这个值,否则会报错
}

摘自  深入理解安卓I 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  jni android native