When using JNI, exceptions may occur, and exceptions need to be handled.
exception handling
JNI throws Throwable exceptions that can be captured at the Java layer with Throwable
In C, only the exception is cleared.
But if an exception is thrown through ThrowNew in JNI, it could have been caught in Java
Example (accessing non-existent attributes in native)
Declaring native methods in Java
public native void exception();
Processing in native
JNIEXPORT void JNICALL Java_com_cj5785_jni_JniTest_exception (JNIEnv *env, jobject jobj) { jclass cls = (*env)->GetObjectClass(env, jobj); jfieldID fid = (*env)->GetFieldID(env, cls, "key0", "Ljava/lang/String;"); //Detecting Java exceptions jthrowable exception = (*env)->ExceptionOccurred(env); if (exception != NULL) { //Clean up abnormal information (*env)->ExceptionClear(env); //Throw exceptions to the Java layer jclass exception_cls = (*env)->FindClass(env, "java/lang/IllegalArgumentException"); (*env)->ThrowNew(env, exception_cls, "key0 is not invalid"); } }
Here, a non-existent property is accessed and exceptions are thrown to Java processing through ThrowNew
Sometimes remedies need to be added to native, depending on the actual application scenario
So when dealing with exceptions, make sure Java works properly.
Cache policy
When the same attribute or object is acquired many times, the use of caching can effectively reduce the memory occupancy of the attribute and object.
Definition in use
Define a static variable to ensure that it generates only one variable, thus saving memory
The life cycle of a local static exists with the program and acts on the block of code it defines.
JNIEXPORT void JNICALL Java_com_cj5785_jni_JniTest_cached (JNIEnv *env, jobject jobj) { jclass cls = (*env)->GetObjectClass(env, jobj); //Set local static variables to ensure that they are assigned only once static jfieldID key_id = NULL; if (key_id == NULL) { key_id = (*env)->GetFieldID(env, cls, "key", "Ljava/lang/String;"); } }
Definition at initialization time
Initialize global variables and store them immediately after loading the dynamic library
Then the call needs to be called immediately after loading.
static { System.loadLibrary("JNITest"); initIds(); } public native static void initIds();
Define the global in native and assign it
jfieldID key_fid; jmethodID random_mid; JNIEXPORT void JNICALL Java_com_cj5785_jni_JniTest_initIds (JNIEnv *env, jclass jcls) { key_fid = (*env)->GetFieldID(env, jcls, "key", "Ljava/lang/String;"); random_mid = (*env)->GetMethodID(env, jcls, "getRandomInt", "(I)I"); }