An introduction to the Android JNI call

Source: Internet
Author: User
Tags case statement

Disclaimer: Welcome Reprint, please specify the source when reproduced! http://blog.csdn.net/flydream0/article/details/7371692

1 description

JNI is the abbreviation for Java Native interface, and Chinese is a native call to Java. Starting with Java1.1, the Java Native Interface (JNI) standard becomes part of the Java platform, which allows Java code to interact with code written in other languages. JNI was initially designed for local compiled languages, especially C and C + +, but it does not prevent you from using other languages, as long as the calling convention is supported.

Since the Android application layer classes are written in Java, these Java classes are compiled into Dex type bytecode and must be run by the Dalvik virtual machine, which plays an important role in Android Dalvik virtual machines. While Android middleware is Writes, the components written by these C/C + + parts are not run on the Dalvik virtual machine. So how does the Java code on the application layer communicate with the components written by C + +?

2 loading. So files

System.loadlibrary (*.so file);

In Java code, you can require VMS to load so files through LoadLibrary, and Java code generally looks like this:

jnitest {    static {        system.loadlibrary (//...} 
The code runtime will look for the libjnitest.so file in the/system/lib/directory and will load the VM so that the Java code and the C components are connected, and there are several ways to call each other.

3 Jni_onload and Jni_onunload

In Android, when the program runs System.loadlibrary ("Jnitest") in the Java layer, after this line of code, the program will load the libjnitest.so file, at the same time, generate a "Load" event, after this event is triggered, By default, the program looks for the Jni_onload function in the list of functions loaded with the. So file and executes, relative to the "load" event, when the loaded. So file is unloaded, the "Unload" event is triggered, and the program defaults to the list of functions loaded in the. so file to find Jni_ OnUnload the function and executes, and then unloads the. so file. It is important to note that the jni_onload and jni_onunload functions are not mandatory in. So components, and users can not implement them, and Java code can call functions in the C component, as described in the next section.

The reason to implement these two functions in the C component (especially the Jni_onload function) is often to do an initialization or "aftercare" work. It is possible to think of jni_onload as the initialization function of the. So component, which is executed when it is first loaded (the DLL file under window can also have a similar mechanism in the _dll_main () function, through a swith Case statement to identify whether it is currently loaded or unloaded). Consider the Jni_onunload function as a destructor, which is called when it is unloaded.

Thus, it is not difficult to understand why many of the JNI C components implement the Jni_onload function. In general, the Jni_onload function in the C component is used to implement the registration interface to the VM, so that the VM can quickly find the C function that the Java code needs to call. (in addition, the Jni_onload function has another feature that tells the VM that the C component uses that JNI version, and if the Jni_onload function is not implemented, the default is JNI version 1.1).

4 Explicit Registration native method 4.1 The role of explicit registration:

The Java category of the application layer is called to the native function through the VM. In general, the VM is searched for the native function in *.so. If you need to call a number of times, you need to look it over and spend a lot of time. At this point, the C component developer can register the local function with the VM, In order to speed up the efficiency of subsequent calls to the native function. Imagine, assuming that the VM inside a native function list, the initial is empty, before the explicit registration of this native function list is empty, each time the Java call native function first in this list to find needs to call the Nativ The e function, if found, is used directly, if not found, We have to go through the list of functions in the. so file, and each time Java calls the native function to do such a process, the efficiency naturally falls, and in order to overcome this, we can do so by loading the. So file into the initialization, the Jni_onload function, First register the native function in the VM's native function list so that each subsequent Java call to the native function will find the corresponding function in the list of native functions in the VM, thus speeding up the speed.

Note: In the Android source development environment, most of the use of display registration native method.

4.2 Under the Android Source code development module, there are two ways to implement the display registration Native method: Method One: Use the jniregisternativemethods defined in the JNIHelp.h header file to implement.

such as ~/working_directory/frameworks/base/services/jni/com_android_server_location_gpslocationprovider.cpp:

Note: Most of the other CPP files in this file sibling directory are explicitly registered with this method for the native method.

Static Jninativemethod smethods[] = {/* Name, signature, Funcptr */{"Class_init_native","() V", (void *) Android_location_gpslocationprovider_class_init_native}, {"Native_is_supported","() Z", (void*) android_location_gpslocationprovider_is_supported}, {"Native_init","() Z", (void*) Android_location_gpslocationprovider_init}, {"Native_cleanup","() V", (void*) Android_location_gpslocationprovider_cleanup}, {"Native_set_position_mode","(IIIII) Z", (void*) Android_location_gpslocationprovider_set_position_mode}, {"Native_start","() Z", (void*) Android_location_gpslocationprovider_start}, {"Native_stop","() Z", (void*) Android_location_gpslocationprovider_stop}, {"Native_delete_aiding_data","(I) V", (void*) Android_location_gpslocationprovider_delete_aiding_data}, {"Native_read_sv_status","([I[f[f[f[i) I", (void*) Android_location_gpslocationprovider_read_sv_status}, {"Native_read_nmea","([BI) I", (void*) Android_location_gpslocationprovider_read_nmea}, {"Native_inject_time","(Jji) V", (void*) Android_location_gpslocationprovider_inject_time}, {"Native_inject_location","(DDF) V", (void*) Android_location_gpslocationprovider_inject_location}, {"Native_supports_xtra","() Z", (void*) Android_location_gpslocationprovider_supports_xtra}, {"Native_inject_xtra_data","([BI) V", (void*) Android_location_gpslocationprovider_inject_xtra_data}, {"Native_agps_data_conn_open","(ljava/lang/string;) V", (void*) Android_location_gpslocationprovider_agps_data_conn_open}, {"Native_agps_data_conn_closed","() V", (void*) android_location_gpslocationprovider_agps_data_conn_closed}, {"Native_agps_data_conn_failed","() V", (void*) android_location_gpslocationprovider_agps_data_conn_failed}, {"Native_agps_set_id","(iljava/lang/string;) V", (void*) android_location_gpslocationprovider_agps_set_id}, {"Native_agps_set_ref_location_cellid","(IIIII) V", (void*) Android_location_gpslocationprovider_agps_set_reference_location_cellid}, {"Native_set_agps_server","(Iljava/lang/string;i) V", (void*) Android_location_gpslocationprovider_set_agps_server}, {"Native_send_ni_response","(II) V", (void*) android_location_gpslocationprovider_send_ni_response}, {void *) Android_location_ Gpslocationprovider_agps_send_ni_message}, {void*) android_location_gpslocationprovider_ Get_internal_state}, {void*) android_location_gpslocationprovider_update_network_state}, }; int register_android_server_location_gpslocationprovider (jnienv* env) { return jniregisternativemethods (env,           
Where Jniregisternativemethods and Nelem are defined in the header file JNIHelp.h, they are:

#include "JNIHelp.h"

In the Android.mk file, add:

Local_shared_libraries +=libnativehelper

Method Two: Use Androidruntime::registernativemethods

such as ~/working_directory/frameworks/base/media/jni/android_media_mediaplayer.cpp:

Note: Most of the other CPP files in the current directory use this method for explicit native registration.

Static Jninativemethod gmethods[] = {{"Setdatasource","(ljava/lang/string;) V", (void *) Android_media_mediaplayer_setdatasource}, {"_setdatasource","(ljava/lang/string; [Ljava/lang/string; [ljava/lang/string;) V ", (void *) Android_media_mediaplayer_setdatasourceandheaders}, {"Setdatasource","(Ljava/io/filedescriptor; JJ) V ", (void *) ANDROID_MEDIA_MEDIAPLAYER_SETDATASOURCEFD}, {"_setvideosurface","(landroid/view/surface;) V", (void *) Android_media_mediaplayer_setvideosurface}, {"Prepare","() V", (void *) Android_media_mediaplayer_prepare}, {"Prepareasync","() V", (void *) Android_media_mediaplayer_prepareasync}, {"_start","() V", (void *) Android_media_mediaplayer_start}, {"_stop","() V", (void *) Android_media_mediaplayer_stop}, { "Getvideowidth",  "() I", (void *) Android_media_ Mediaplayer_getvideowidth}, {void *) Android_media_mediaplayer_getvideoheight}, {void *) android_media_mediaplayer_seekto},    //...} //this function only registers the native Methodsstatic int register_android_media_mediaplayer (jnienv *env) {    return Androidruntime::registernativemethods (env,                  "Android/media/mediaplayer", Gmethods, Nelem (Gmethods));}   
Where androidruntime::registernativemethods is defined in the header file Android_runtime/androidruntime.h, when used:

#include "android_runtime/androidruntime.h"
And in the Android.mk file, add:

Local_shared_libraries + =     libandroid_runtime

For function naming, please refer to another article in the blog: How to provide an interface summary by using the Jni method under Android.

Note: The above two explicit registration native methods are only applicable to the Android source development environment, as for the Android NDK environment How to explicitly register the native method, has not been studied, and these two methods are currently not supported by the NDK, The NDK development model generally uses the implicit registration native function, which is what is to be said next.

5 Implicit Registration Native method

As mentioned in section 3rd above, the Jni_onload and jni_onunload functions are not mandatory, in which case it is equivalent to loading the. So file without an initialization function, and since there is no initialization function, the explicit registration of the native method will not work. Then how do you get the Java code from the application layer to call the lower C function?

Fortunately, even if we do not use any code to do the native function explicit registration, the Java code of the application layer will use the default method to find the corresponding native function in the list of functions in the transferred. so file when calling the native function, except that This native function has a default correspondence with the name of the native function declared in the Java type. Such as:

The native member function of the Java class: public native int socket_send (int cmdid,string argus), the default is to find Jint jnicall java_com_hase_ in the list of functions in the. so file Bclm_bclm_socket_1send (jnienv *env, Jobject obj, Jint cmdid, jstring Argus); function, once the corresponding function is found, The VM automatically registers this native function in the native function list inside the VM to expedite subsequent same JNI calls.

But then the question is, how do we, as yards, know that the Java Native member function corresponds to the name of the native function in the C component? Simply function name Maybe we can fix it. Fortunately, the JDK provides a javah tool that can be used to automate the generation of C component header files using the. class file.

For example, you write a Xxx.java file in Java, the Java type inside the declaration of some native member functions, the Xxx.java file compiled will generate Xxx.class files, then the Xxx.class package you generated in the directory input command line:

$javah-jni Com.packagename.yourclassname
A header file is generated in the current directory.

Like what:

Javah-jni Com.test.example

The com_test_example.h header file is generated under the current directory.

The COM structure under the current directory is: Com/test/example.class

Copy this header file into your C component project and implement the native function declared in it.

As already stated in the relevant section of the explicit registration of the native function, explicit registration is the addition of the native function to the native function list inside the VM to speed up the efficiency of subsequent JNI calls, in fact, at the time of the implicit native registration, each time a JNI call is executed, Once the VM finds the corresponding native function in the list of. So functions, it also registers it in the native function chain list inside the VM, thus seeing that the implicit native registration method is slightly slower than the first time a JNI call is used, and subsequent calls are directly in the native function list inside the VM Find the corresponding native function, so it seems that the explicit and implicit registration native method, in fact, the efficiency is similar.

OK, it's over!

An introduction to the Android JNI call

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.