Analysis of JNI and HAL instances based on Android2.3.5 [1]

Source: Internet
Author: User

Analysis of JNI and HAL instances based on Android2.3.5 [1]
 

I. Introduction to JNI in Android

The full name of JNI in Android is Java Native Interface (JNI). The JNI standard is part of the java platform. It allows Java code to interact with code written in other languages. JNI is a local programming interface that enables the Java code running inside the Java Virtual Machine (VM) to work with other programming languages (such as C, C ++, and assembly languages) write Applications and libraries for interaction.

Ii. Why does Java introduce JNI?

JNI is widely used in Android systems. The Android system is implemented in C/C ++ at the underlying layer, and the APIS provided in the upper layer are implemented in Java. Java calls the underlying implementation through JNI.

 

Virtual machines in the Java World are written in the Native language. virtual machines run on specific platforms. virtual machines themselves cannot be unrelated to the platform. jni can shield different operations on different platforms from the java layer, in this way, the platform-independent features of java can be implemented. Adapt to technologies that have been implemented in Native. Some efficiency issues require Native language implementation.

 

In Java, JNI is mainly implemented for the preceding purposes. The MediaPlayer class of the API Multimedia Interface in Anroid actually calls the libmedia library through JNI at the underlying layer. The existence of JNI allows us to reuse many existing C/C ++ libraries, saving the trouble of repeated development, in addition, many open-source libraries can be used (there are many open-source libraries in the Android library, such as libjpeg and libpng ), in addition, it makes the program we develop more efficient (C/C ++ code achieves the best hardware performance ).

Iii. JNI calling process in Java

In the world of Java, JNI can be seen as a proxy mode for the application itself. For the beginning, you need to use C/C ++ to implement a proxy program to actually operate the target native function. In Java, the JVM indirectly calls the target native function by loading and calling the JNI program. Its call is as follows:

Figure 1: JNI calling process in Android (the Load DLL and DLL are determined based on different environments)

The general steps for JNI Program Development in Android Java are as follows:

Compile the calling class in JAVA; Use javah to generate the header file of the native function of C/C ++; call other functions required in C/C ++ to implement the native function; add all native libraries and resources dependent on the project to the java project path, generate JAVA programs, and publish JAVA applications and so libraries;

 

Iv. JNI syntax in Android

The JNI In the Android system Java can be seen as a proxy mode for the application itself. For the starters, you need to use C/C ++ to implement a proxy program to actually operate the target native function. The basic data type conversion is as follows:

Figure 2: Basic data type conversion table

Note: The symbolic attribute is in the JNI environment.

Reference the data type conversion table as follows:

Figure 3: reference data type conversion table

V. JNI registration function in Java

JNI naming rules in Java: For the JNI layer, "to" _ ". In this way, you can find the path and file of your JNI layer. You can register Native functions in two ways: static registration and dynamic registration. Static registration static is to establish the association between java and jni functions based on the function name, And the jni layer function name must follow a specific format. Its disadvantage is: all classes declared in java need to be compiled; jni-layer functions generated by javah are particularly long; when the native function is called for the first time, the corresponding jni-layer functions need to be searched by name to establish association relationships, this affects efficiency. Therefore, the dynamic registration method is described in detail here. Java native and JNI establish a connection through the JNINativeMethod structure. The structure content is as follows:

 

Typedef struce {const char * name; // name of the native function in java, without carrying the path const char * signature of the package; // signature information of the java function, represented by a string, void * fnptr is a combination of the parameter type and return value type. // function pointer corresponding to the JNI layer. Note that it is the void * type. } JNINativeMethod;
Use an instance in the Anroid system to give a perceptual understanding and explanation. (Please download the Anroid code of OK6410 of Anroid2.3.4 online, which is consistent with the path in this article, because I port OK6410 of Android2.3.4 to the platform of Android2.3.5 myself) the path is android2.3.5/frameworksaseservicesorlinx_pwm_jniPwmJniService.cpp, which is a JNI controlled by PWM. The details are as follows:

 

 

Figure 4: The JNINativeMethod method Android provides a RegisterNatives (JNIEnv * env, Const char * className, Const limit * gMethods, int numMethods) to implement this function. In fact, there is also a AndroidRuntime. cpp also implements a RegisterNatives function. The functions of the two are the same, as shown below:

 

 

Let's take a look at the JNI Dynamic Registration in the PwmJniService. cpp function, as shown below:

 

In the JNI_OnLoad function, the register_forlinx_server_PwmService () function is called, and the definition of this function is as follows:

Let's take a look at this line of code: static const char * const kClassName = forlinx_pwm_server/server/PwmService; that is, find the corresponding library through kClassName, and this PwmService is in the Android2.3.5/hosts file, as follows:

That is to say, the Java layer uses this method to implement the Java layer to call the C/C ++ layer library, so that the Anroid underlying layer is encapsulated, in Android, The JNI layer calls the HAL layer of Android, while the HAL layer calls the Linux driver !!

Vi. JNI garbage collection
The objects created in Java are finally recycled and released by the garbage collector. For JNI, reference to the objects directly does not increase the reference count value, after the result is returned from JNI, the objects referenced in JNI may be recycled by the garbage collector, and the pointer recorded under JNI may be a wild pointer. To solve this problem, the JNI specification provides the following three types of references:

 

Local Refrence: Local reference. All non-global variables used in the JNI layer functions use Local Refrence. It contains the jobject passed in when the function is called and the jobject created in the JNI layer function, the biggest feature is that once the JNI layer function returns, these jobject may be reclaimed. Global Refrence: Global reference. This type of reference will remain in the memory if the program does not actively call the destroy interface. Weak Global Refrence: Weak Global reference, which may be released during use. Call the IsSameObject function in JNIEnv to determine whether it still exists. 7. Signature information of the JNI function in JavaIn the Android system, the writing rules of the JNI Signature in Jave are as follows: () indicates a parameter, and the following indicates a return value. For example, "() V" indicates void func (), "(II) V" indicates void func (int, int) and so on. The specific correspondence between each character is as follows:
If the java function parameter is a class, it starts with "L" and ends with ";", with the package and class names separated by "/" in the middle, the parameter of the corresponding C function name is jobject. An exception is the String class, and its corresponding class is jstring. As follows:
          Ljava/lang/String;    String     jstring          Ljava/net/Socket;     Socket     jobject
The following uses the static const JNINativeMethod gMethods [] Array Function in android2.3.5/frameworksaseservicesorlinx_pwm_jniPwmJniService.cpp as an example:
Select the forlinx_set_freq function to illustrate the JNI signature problem. You can see in {_ Set_freq, (I) Z, (void *) forlinx_set_freq },With this definition method, we can see the signature parsing table in the above table at a glance. The forlinx_set_freq function is defined as follows:
We can see that the returned type of forlinx_set_freq is: Jboolean, And JbooleanThe JNI signature is: Z, and Jint freqIs a value that needs to be set in the forlinx_set_freq function, and JintThe JNI signature is: I. Therefore, the signature information of the forlinx_set_freq function is: (I) Z.

 

Related Article

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.