"Go" in-depth understanding of the JNI---registration native function on the Android platform

Source: Internet
Author: User

Original URL: http://my.oschina.net/u/157503/blog/169041

There are two ways to register the native function: static registration and dynamic registration.

1. Static Registration method

The 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

The disadvantages of a particular format are:

1) The JNI layer functions generated by Javah are particularly long;

2) The first call to the native function should be based on the name of the corresponding JNI layer function to establish a correlation, which affects efficiency.

2. Dynamic Registration method

JNI allows you to provide a function mapping table that is registered with the Jave virtual machine so that the JVM can invoke the corresponding function using the function mapping table.

It is not necessary to find the function that needs to be called by the function name.

Java and JNI are connected by 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 the function in Java.

The second variable, signature, uses a string to describe the function's arguments and return values

The third variable, fnptr, is the function pointer, which points 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, call it,

The job of dynamic registration is done here.

1) jni_onload () function

The Jni_onload () function is called when the VM executes the system.loadlibrary (XXX) function, which has two important functions:

Specify the JNI version: Tell the VM that the component uses the JNI version (if the Jni_onload () function is not provided, the VM defaults to the oldest version of JNI 1.1), and if you want to use the new release of JNI,

For example, JNI version 1.4, the Jni_onload () function must return a constant jni_version_1_4 (which is defined in jni.h) to inform the VM.

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) registernatives

Registernatives defined in Androidruntime.

Syntax

Jint registernatives (Jclass clazz, const jninativemethod* methods,jint nmethods)

3. Add a custom native function to Android

The role of JNI in the Android hierarchy is as follows:

In Android, the main JNI code is in the following path:

Android Source root directory/frameworks/base/core/jni/

The contents of this path will be compiled into a library libandroid_runtime.so, which 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, for example, In the JNI directory frameworks/base/media/jni/of the media section, it is compiled into a library libmedia_jni.so.

Each file in JNI is actually a plain file of C + +, and its naming generally corresponds to a supported Java class.

This kind of relationship is a customary notation, not a compulsion.

1) Registering the Jni method

There is a onload.cpp file in the Android source root directory/frameworks/base/services/jni/directory, 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;

}

Onload.cpp file is the declaration of the registration function, the lower part is called the various registration functions, and these registers function is the JNI method registration function! 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 registration function is implemented.

Open Com_android_service_helloservice.cpp File

2) Add the implementation code of 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, and the third parameter is a 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) {

val = value;

Logi ("Hello jni:set value%d to device.", Val);

}

Static Jint Hello_getval (jnienv* env, Jobject clazz) {

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) {

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},

{"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));

}

}

This article welcome reprint, Reprint please indicate the source and the author

Source: Http://blog.sina.com.cn/staratsky

Meteor

"Go" in-depth understanding of 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.