1.注册JNI函数

来源:互联网 发布:保留两位小数 java 编辑:程序博客网 时间:2024/05/16 10:33

  • 生成头文件
    1.编写Java代码,编译生成 .class 文件
    2.使用Java的javah,javah -o output packagename.class
    生成output.h的JNI头文件,其中声明了对应的native函数
  • 静态注册
    静态方法根据函数名建立Java函数和JNI函数之间的关联关系

  • 动态注册
    通过JNINativeMethod的结构体保存两个函数的对应关系

    typedef struct {  //Java中native 函数的名字,不包含包的路径  const char* name;  // Java函数的签名信息,参数的类型和返回值类型的组合  const char* signature;  void* fnPtr;}JNINativeMethod;

    AndroidRunTime 类提供了一个registerNativeMethods函数完成注册工作

    [-->AndroidRunTime.cpp]int AndroidRuntime::registerNativeMethods(JNIEnv* env,const char* className,const JNINativeMethod* gMethods,int numMethods){  //调用jniRegisterNativeMethods完成注册  return jniRegisterNativeMethods(env,className,gMethods,numMethods);}
    [-->android_media_MediaScanner.cpp]//注册JNINativeMethod数组int register_android_media_MediaScanner(JNIEnv *env){//调用AndroidRuntime的registerNativeMethods函数,第二个参数表明是Java的哪个类return AndroidRuntime::registerNativeMethods(env,"android/media/MediaScanner",gMethods,NELEM(gMethods));}
    int jniRegisterNativeMethods(JNIEnv* env,const char* className,const JNINativeMethod* gMethods,int numMethods){  jclass clazz;  clazz = (*env)->FindClass(env,className);  ......  //实际上调用JNIEnv的RegisterNavtives 函数完成注册的  if ((*env)->RegisterNatives(env,clazz,gMethods,numMethods)<0){      return -1;  }  return 0;}

    env 指向一个JNIEnv结构体,classname 为对应的Java类名,由于JNINativeMethod
    中使用的函数名并非全路径,所以要指明哪个类。
    当Java层通过System.loadLibrary加载完JNI动态库后,紧接着会查找该库中一个叫JNI_OnLoad
    的函数,如果有则调用它,在其中调用register_android_media_MediaScanner(JNIEnv *env)
    完成动态注册

0 0