What is jni library




















In terms of performance, native code used to be up to 20 times faster than Java, when running in interpreted mode. In fact, the java command-line utility is an example of one such application, that launches Java code in a Java Virtual Machine. It adapts Java method signatures to native function prototypes jni.

JNI data type mapping in variables. Create a Java class with native method s : public native void sayHi String who, int times ; 2. Load the library which implements the method: System. Invoke the native method from Java For example, our Java code could look like this:. Doing so will ensure that you have sufficient stack space, that you're in the correct ThreadGroup , and that you're using the same ClassLoader as your Java code.

Attaching a natively-created thread causes a java. Thread object to be constructed and added to the "main" ThreadGroup , making it visible to the debugger. Calling AttachCurrentThread on an already-attached thread is a no-op. Android does not suspend threads executing native code. If garbage collection is in progress, or the debugger has issued a suspend request, Android will pause the thread the next time it makes a JNI call.

If coding this directly is awkward, in Android 2. Similarly, to call a method, you'd first get a class object reference and then a method ID. The IDs are often just pointers to internal runtime data structures. Looking them up may require several string comparisons, but once you have them the actual call to get the field or invoke the method is very quick.

If performance is important, it's useful to look the values up once and cache the results in your native code.

Because there is a limit of one JavaVM per process, it's reasonable to store this data in a static local structure. The class references, field IDs, and method IDs are guaranteed valid until the class is unloaded.

Classes are only unloaded if all classes associated with a ClassLoader can be garbage collected, which is rare but will not be impossible in Android. Note however that the jclass is a class reference and must be protected with a call to NewGlobalRef see the next section. If you would like to cache the IDs when a class is loaded, and automatically re-cache them if the class is ever unloaded and reloaded, the correct way to initialize the IDs is to add a piece of code that looks like this to the appropriate class:.

The code will be executed once, when the class is initialized. If the class is ever unloaded and then reloaded, it will be executed again. Every argument passed to a native method, and almost every object returned by a JNI function is a "local reference".

This means that it's valid for the duration of the current native method in the current thread. Even if the object itself continues to live on after the native method returns, the reference is not valid. This applies to all sub-classes of jobject , including jclass , jstring , and jarray. The runtime will warn you about most reference mis-uses when extended JNI checks are enabled.

If you want to hold on to a reference for a longer period, you must use a "global" reference. The NewGlobalRef function takes the local reference as an argument and returns a global one. The global reference is guaranteed to be valid until you call DeleteGlobalRef. This pattern is commonly used when caching a jclass returned from FindClass , e.

All JNI methods accept both local and global references as arguments. It's possible for references to the same object to have different values. For example, the return values from consecutive calls to NewGlobalRef on the same object may be different.

To see if two references refer to the same object, you must use the IsSameObject function. One consequence of this is that you must not assume object references are constant or unique in native code. The bit value representing an object may be different from one invocation of a method to the next, and it's possible that two different objects could have the same bit value on consecutive calls.

Do not use jobject values as keys. Programmers are required to "not excessively allocate" local references. In practical terms this means that if you're creating large numbers of local references, perhaps while running through an array of objects, you should free them manually with DeleteLocalRef instead of letting JNI do it for you. They may be passed between threads, and are valid until the matching Release call. One unusual case deserves separate mention. If you attach a native thread with AttachCurrentThread , the code you are running will never automatically free local references until the thread detaches.

Any local references you create will have to be deleted manually. In general, any native code that creates local references in a loop probably needs to do some manual deletion. Be careful using global references. Global references can be unavoidable, but they are difficult to debug and can cause difficult-to-diagnose memory mis behaviors. All else being equal, a solution with fewer global references is probably better. The Java programming language uses UTF The nice thing about this is that you can count on having C-style zero-terminated strings, suitable for use with standard libc string functions.

If possible, it's usually faster to operate with UTF strings. Don't forget to Release the strings you Get. They are guaranteed valid until Release is called, which means they are not released when the native method returns. A common mistake is reading character data from a file or network stream and handing it to NewStringUTF without filtering it.

If you don't, the UTF conversion is likely to provide unexpected results. CheckJNI—which is on by default for emulators—scans strings and aborts the VM if it receives invalid input.

JNI provides functions for accessing the contents of array objects. While arrays of objects must be accessed one entry at a time, arrays of primitives can be read and written directly as if they were declared in C. Either way, the raw pointer returned is guaranteed to be valid until the corresponding Release call is issued which implies that, if the data wasn't copied, the array object will be pinned down and can't be relocated as part of compacting the heap.

You must Release every array you Get. You can determine whether or not the data was copied by passing in a non-NULL pointer for the isCopy argument. This is rarely useful. The Release call takes a mode argument that can have one of three values. The actions performed by the runtime depend upon whether it returned a pointer to the actual data or a copy of it:.

By writing programs using the JNI, you ensure that your code is completely portable across all platforms. Programmers use the JNI to write native methods to handle those situations when an application cannot be written entirely in the Java programming language. For example, you may need to use native methods and the JNI in the following situations: The standard Java class library may not support the platform-dependent features needed by your application. You may already have a library or application written in another programming language and you wish to make it accessible to Java applications.

You may want to implement a small portion of time-critical code in a lower-level programming language, such as assembly, and then have your Java application call these functions. Programming through the JNI framework lets you use native methods to do many operations. Native methods may represent legacy applications or they may be written explicitly to solve a problem that is best handled outside of the Java programming environment.

The JNI framework lets your native method utilize Java objects in the same way that Java code uses these objects. A native method can create Java objects, including arrays and strings, and then inspect and use these objects to perform its tasks.



0コメント

  • 1000 / 1000