Learn more about the JNI---registration native function on the Android platform

Source: Internet
Author: User

There are two ways to register the native function: static registration and dynamic registration. 1. Static Registration MethodThe corresponding JNI function is found according to the function name: When the Java layer calls the function, it will look for the function from the corresponding JNI, if not, an error will be established, if there is an association connection, then the function will be used directly at the time of invocation, and this part of the operation is done by the virtual machine. The static method iterates through the association between the Java and JNI functions according to the function name, and requires that the name of the JNI layer function must follow a specific format, with the disadvantage that: 1) the JNI layer function generated by Javah is particularly long 2) The first call to the native function is to search for the corresponding JNI layer function according to the name, which affects the efficiency. 2. Dynamic Registration MethodJNI allows you to provide a function mapping table and register it with the Jave virtual machine so that the JVM can invoke the function using the function mapping table so that it does not have to find the function that needs to be called by the function name. Java and JNI are established through the structure of Jninativemethod, which is defined in the jni.h, with the following structure: typedef struct {const char* name;const char* signature;void* Fnptr;} Jninativemethod; The first variable name is the name of a function in Java. The second variable, signature, uses a string that describes the function's arguments and the return value of the third variable fnptr is the function pointer, pointing to the C function. Once Java has loaded the JNI dynamic library through System.loadlibrary, it will then look for a jni_onload function, and if so, invoke it, and the work of dynamic registration is done here. 1) the Jni_onload () function jni_onload () function is called when the VM executes the system.loadlibrary (XXX) function, and it has two important functions: Specify the JNI version: Tell the VM that the component uses that JNI version (if not provided jni_ The OnLoad () function, which defaults to using the oldest JNI version 1.1), if you want to use the new version of JNI, such as JNI version 1.4, you must tell the VM by the Jni_onload () function to return the constant jni_version_1_4, which is defined in jni.h. Initialization setting, when the VM executes to the System.loadlibrary () function, the Jni_onload () method is called immediately, so the initialization of various resources in the method is most appropriate, 2) Registernativesregisternatives defined in Androidruntime syntax:jint registernatives (jclass clazz, const JNINativeMethod* Methods,jint nmethods) 3. Add a custom native function to AndroidThe role of JNI in the Android hierarchy is as follows:
    in Android, the main JNI code is in the following path: Android source root/frameworks/base/core/jni/The contents of this path will be compiled into a library libandroid_ Runtime.so, this is an ordinary dynamic library that is placed in the/system/lib directory of the target system. In addition, Android also contains other JNI libraries, such as the JNI directory frameworks/base/media/jni/in the media section , the individual files that are compiled into the library Libmedia_jni.so.JNI are actually ordinary C + + files that have a corresponding relationship with the supported Java classes. This kind of relationship is a customary notation, not a compulsion.  1) registered Jni method in the Android source root directory/frameworks/base/services/jni/directory has a onload.cpp file, adding the JNI function declaration and the JNI function registration method # include " JNIHelp.h "   #include" jni.h "   #include" utils/log.h "   #include" utils/misc.h "     namespace Android { int register_android_server_alarmmanagerservice (JNIEnv* env);  int Register_android_server_batteryservice (jnienv* env);  int Register_android_server_inputapplicationhandle (jnienv* env);  int Register_android_server_inputwindowhandle (jnienv* env);  int Register_android_server_inputmanager (jnienv* env);  int Register_android_server_lightsservice (jnienv* env);  int Register_android_server_powermanagerService (jnienv* env);  int Register_android_server_usbdevicemanager (jnienv* env);  int Register_android_server_usbhostmanager (jnienv* env);  int Register_android_server_vibratorservice (jnienv* env);  int Register_android_server_systemserver (jnienv* env);  int Register_android_server_location_gpslocationprovider (jnienv* env);  int Register_android_server_connectivity_vpn (jnienv* env);  int Register_android_server_helloservice (jnienv *env);  //Add a custom JNI function statement here};    using namespace Android;    extern "C" 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 ("GetEnv failed!");          return result;      }      log_assert (env, "Could not retrieve the env!");        register_android_server_powermanagerservice (env);      register_android_server_inputapplicationhandle (env);      register_android_server_inputwindowhandle (env);      register_android_server_inputmanager (env);      register_android_server_lightsservice (env);      register_android_server_alarmmanagerservice (env);      register_android_server_batteryservice (env);      register_android_server_usbdevicemanager (env);      register_android_server_usbhostmanager (env);      register_android_server_vibratorservice (env);      register_android_server_systemserver (env);      register_android_server_location_gpslocationprovider (env);      register_android_server_connectivity_vpn (env);      register_android_server_helloservice (env); JNI method Registration       return jni_version_1_4;  } The   onload.cpp file is partially a declaration of a registered function, and the lower part is called a variety of registration functions, which are the registration functions of the JNI Method! It is through these registration functions that the upper layer can invoke the registered Jni method. Take Register_android_server_helloservice as an example to see how a registered function is implemented. Open Com_android_service_helloservice.cpp file  2) Add the implementation code for the registration function, as follows: int Register_android_server_helloservice (JNIENV * ENV) {         return jniregisternativemethods (env, "Com/android/ Server/helloservice ", Method_table, Nelem (method_table));  }   #其中jniRegisterNativeMethods为注册JNI方法函数, #此函数的第二个参数为对应着java类即HelloService. java file name, third parameter is the registered method table  3) Join the JNI method table  static const Jninativemethod method_table[] = {     {"init_native", " () Z ", (void*) Hello_init},      {" Setval_native "," (I) V ", (void*) Hello_setval},      {" Getval_native "," () I ", (void*) Hello_getval},  };  4) Implementation code for each interface in the method table static void Hello_setval (jnienv* env, Jobject clazz, Jint value) {     & Nbsp;val = value;      logi ("Hello jni:set value%d to device.", Val);  }  static jint Hello_getval (jnienv* env, Jobject clazz) {        & nbsp Logi ("Hello jni:get value%d from device.", Val);          return Val;      }  static Jboolean Hello_init (jnienv* env, Jclass clazz) {          logi ("Hello jni:initializing ...");          return-1;            }      The complete code is as follows: namespace android{  int val;  static void Hello_seTval (jnienv* env, Jobject clazz, Jint value) {      val = value;       logi ("Hello jni:set value%d to device.", Val);    }    static jint Hello_getval (jnienv* env, Jobject clazz) {    & Nbsp;    logi ("Hello jni:get value%d from device.", Val);          return Val;      }  static Jboolean Hello_init (jnienv* env, Jclass clazz) {          logi ("Hello jni:initializing ...");          return-1;            }   static Const Jninativemethod method_table[] = {     {"init_native", "() Z", (void*) Hello_init},       {"Setval_native", "(I) V", (void*) Hello_setval},    &Nbsp; {"Getval_native", "() I", (void*) Hello_getval},     };    int Register_android_server_helloservice (jnienv *env) {         return Jniregisternativemethods (env, "Com/android/server/helloservice", Method_table, Nelem (method_table));     }  }

Learn more about the JNI---registration native function on the Android platform

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.