JNI is an abbreviation of Java Native Interface. It is a kind of standard that provides many apis to enable Java to communicate with C/C++. The JNI interface is the bridge between the Java layer world and the C/C++ language world.
Exploration: Why use JNI?
1. Use existing open source libraries. Many of the best open source libraries are written in C/C++.
2. Code protection: Java code of Android APK is easy to decompile, while C/C++ is more difficult to decompile.
3. Easy portability, libraries written in C/C++ can be easily used in other embedded platforms.
I. Mutual invocation between Java layer and Native layer through JNI interface
Now look at the following diagram, which perfectly illustrates the rules of the JNI interface.
The first part of this picture is the familiar Java layer development on the left, and the middle part is the use of the JNI interface to call the relevant C/C++ functions. How does C/C++ call Java code? This is where reflection comes in, and the JNI interface provides many functions to call.
Two: JNI interface
JNI interface is an interface provided by Google developers to facilitate the communication between Java layer and C/C++ layer. The corresponding interface description document is in the “jni.h” header file.
This row is the data type in the JNI interface, and the data type is simply preceded by the letter J, which is easy to remember. As shown in the figure below.
Next comes the object, array, and so on, as shown in the figure below.
Next, JNI functions are of the following types. The call-starting function literally means “Call”, in this case, invoking Java layer methods through reflection. The function that starts with Get literally means Get, in this case getting the value of a Java layer field by reflection; The function at the beginning of Set literally means Set, in this case modifying the value of a Java layer field through reflection; New starts with creating other types of functions.
jclass (FindClass)(JNIEnv, const char*);
jmethodID (GetMethodID)(JNIEnv, jclass, const char*, const char*);
jobject (CallObjectMethod)(JNIEnv,jobject,jmethodID, …) ;
jfieldID (GetFieldID)(JNIEnv, jclass, const char*, const char*);
jobject (GetObjectField)(JNIEnv, jobject, jfieldID);
void (SetObjectField)(JNIEnv, jobject, jfieldID, jobject);
jmethodID(GetStaticMethodID)(JNIEnv,jclass,const char*,constchar*);
jobject (CallStaticObjectMethod)(JNIEnv,jclass, jmethodID, …) ;
jfieldID (GetStaticFieldID)(JNIEnv,jclass,const char*,const char*);
jobject (GetStaticObjectField)(JNIEnv, jclass, jfieldID);
void (SetStaticObjectField)(JNIEnv, jclass, jfieldID, jobject);
jstring (NewStringUTF)(JNIEnv, const char*);
Let’s look at the JNI interface functions above.
(1) Call Java layer ordinary methods
Jobject: Return value, in this case Jobject is returned.
(*CallObjectMethod) : The normal method is called here.
(JNIEnv*,jobject,jmethodID, …) : Indicates the parameter list.
The first argument is JNIEnv*, which is a local call interface that provides a number of JNI interface functions to call. The second argument is the jobject object. The third parameter is the method ID, which can be obtained from the GetMethodID function. “…” Represents the parameter list information of the calling method.
What is Get MethodID?
GetMethodID = GetMethodID; GetMethodID = GetMethodID;
JmethodID: returns the Java layer methodID.
(*GetMethodID) : gets the ID of a common method.
(JNIEnv*, jclass, const char*, const char*) : parameter list information.
The second argument to this function is jclass, which can be obtained through the FindClass function. The third parameter is the name of the Java layer method, and the fourth parameter is the signature information of the Java layer method.
Explore: What is FindClass?
The FindClass function retrieves a Java class by reflection, as follows:
Jclass: The return value, in this case, is the Java class.
(*FindClass) : Reflection gets Java classes.
(JNIEnv*, const char*) : parameter list information.
(2) Get the value of the Java layer instance field
Jobject: Return value, in this case Jobject is returned.
(*GetObjectField) : Gets the value of the Java layer instance field.
(JNIEnv*, jobject, jfieldID) : Parameter list information. The third parameter is the instance field ID, which can be obtained by using the GetFieldID function as follows:
JfieldID: Return value, which is the instance fieldID.
(*GetFieldID) : Gets the instance field ID.
(JNIEnv*, jclass, const char*, const char*) : parameter information. The third argument to this function is the instance field name, and the fourth argument is the signature information for the instance field.
(3) Set the value of the Java layer instance field
Void: The return value is Void.
(*SetObjectField) : Sets the value of the Java layer instance field.
(JNIEnv*, jobject, jfieldID, jobject) : parameter information. The fourth parameter is the value to be set for the Java layer instance field.
(4) Call Java layer static methods
Jobject: Return value, in this case Jobject is returned.
(*CallStaticObjectMethod) : Static methods are called here.
(JNIEnv*,jclass, jmethodID, …) : Indicates the parameter list. The first argument is JNIEnv*, which is a local call interface that provides a large number of JNI interface functions for us to call. The second parameter is jclass. The third parameter is the static MethodID, which can be obtained using the GetStatic MethodID function. Behind the “…” Represents the parameter list information of the calling method.
What is GetStaticMethodID? **
Use the GetStaticMethodID function to get the Java layer static method ID as follows:
JmethodID: returns the Java layer methodID.
(*GetStaticMethodID) : Gets the ID of the static method.
(JNIEnv*, jclass, const char*, const char*) : parameter list information.
The second argument to this function is jclass, which can be obtained through the FindClass function. The third parameter is the name of the Java layer method, and the fourth parameter is the signature information of the Java layer method.
(5) Get the value of the Java layer static field
Jobject: Return value, in this case Jobject is returned.
(*GetStaticObjectField) : Gets the value of the Java layer static field.
(JNIEnv*, jclass, jfieldID): Parameter list information. The third parameter is the static field ID, which can be obtained using the GetStaticFieldID function, as follows:
JfieldID: Return value, which is the instance fieldID.
(*GetStaticFieldID): Gets the ID of a static field.
(JNIEnv*, jclass, const char*, const char*): parameter information. The third argument to this function is the static field name, and the fourth argument is the signature information for the static field.
(6) Set the value of the Java layer static field
Void: The return value is void.
(*SetStaticObjectField): Sets the value of the Java layer static field.
(JNIEnv*, jclass, jfieldID, jobject): parameter information. The fourth parameter is the value to be set for the Java layer static field.
(7) New start function is to create, with the help of New start function API to create the corresponding basic type, array, object, prototype: Jstring: return value Jstring.
(*NewStringUTF) : Creates a utF-8 encoded string.
(JNIEnv*, const char*) : parameter list information. The second argument is a value of type char*, where you can enter the string you want to create.
Summary:
The JNI interface is the implementation of Java layer and C/C++ layer to call each other, as well as common JNI interface functions and their purposes, as shown in the following table.