JNI
JNI is a Java Local interface. It defines the method for managing code and interacts with local code. In other words, Java interacts with C/C ++. We should carefully understand JNI on j2se 6. Understand its functions. For more details, visit the JVA official website.
JavaVM and jnienv
JNI defines two key data structures: JavaVM and jnienv. Essentially, you can understand them as pointers to function tables. JavaVM provides APIs to create and destroy itself. Theoretically, each process allows multiple javavms, but only one of them is allowed on Android. Jnienv provides most JNI functions. All your local functions receive a jnienv as the first parameter.
Jnienv is used for local thread storage. The reason is:You cannot share a jnienv between two threads.If a piece of code has no way to obtain its jnienv, you should share JavaVM and use getenv to discover the jnienv of the thread.
Declarations on C, jnienv, JavaVM, and C ++ are different."jni.h"
The include file provides different typedefs, depending on whether you include C or C ++. For this reason, it is not good to include the jnienv parameter in the header files of the two languages.
Threads
All threads are Linux threads and are scheduled by the kernel. They generally start with managed code (such as thread. Start), but they can also be created elsewhere and then connected to JavaVM. For example, a thread usespthread_create
Created by JNI
OfAttachCurrentThread
OrAttachCurrentThreadAsDaemon
Function. Before a thread is connected, JNI cannot be called without jnienv.
Android does not suspend threads that are executing local code. If GC (garbage collection) is being processed, or the debugger sends a pending request, Android will pause the thread next time and use a JNI call.
In addition, we need to use JNI to callDetachCurrentThread
To connect threads, provided that the call is executed before these threads exit.
Jclass, jmethodid, jfieldid
If you want to access the value range (or attribute) of an object from the local code, you should do this:
- Use findclass to obtain a reference to a Class Object
- Use
GetFieldID
Obtain a domain ID
- Filter the domain types you need, for example
GetIntField
Similarly, if you want to call a method, you first obtain the reference of a class object and then obtain a method ID. These IDS are usually pointers in the internal runtime data structure. Searching for them may require several strings for comparison. Once you actually call them, It is very fast to obtain the value or call method.
If the performance requirements are high, it is useful to search for these values and cache the results in your local code. Because each process has only one JavaVM restriction, it is reasonable to store the data in a static local structure.
Before a class is detached, its reference, value ID and method ID are valid.
When a class is loaded, If You Want To Cache IDs and automatically recache them when the classes are uninstalled and reloaded, the correct method is to initialize these IDs and add the following code:
Private Static native void nativeinit ();
// Static block syntax. If you are not familiar with it, add the Java
Static {
Nativeinit ();
}
Note that the above code is executed only once, that is, when the class is initialized for the first time, no matter how many times your class is new, nativeinit () is executed only once, unless you detach this class, it will be executed only after it is reloaded.
UTF-8 and UTF-16 strings
The Java programming language uses UTF-16. For convenience, JNI provides a way to make it work on the UTF-8 after modification. The modified encoding is useful for C because it uses 0xc0 0x80 encoding \ u0000 instead of 0x00.
If possible, using UTF-16 will be faster.