当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 ; //必须返回这个值,否则会报错 }
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/qingchunweiliang/article/details/48136363