Tag: SSO message returns String class Exce ack Roc place
In Java programming, we often encounter a variety of exceptions, and also handle various exceptions. Handling exceptions is very simple in Java, we usually use try-catch-finally to handle them, or we can simply throw an exception with throw. So how do we deal with exceptions when it comes to JNI programming?
Exception handling Process
The JNI specification has done everything we need to do. Recall the process of handling exceptions:
- We first have to detect anomalies where there may be anomalies.
- Handling Exceptions
Yes, I think the exception of the processing is simple to summarize as a two-step, in the exception processing we usually print stack information and so on. In JNI programming, the idea of exception handling should be similar, and the process can be expressed as:
In JNI I need to manually clear the exception. Therefore, the exception handling in JNI should be strictly followed: check-and-process, clean-up process, in the diagram I also think that the removal is one of the steps of processing.
Exception handling Functions in JNI
There are definitions of the following related functions in jni.h:
jint (*Throw)(JNIEnv*, jthrowable); jint (*ThrowNew)(JNIEnv *, jclass, const char *); jthrowable (*ExceptionOccurred)(JNIEnv*); void (*ExceptionDescribe)(JNIEnv*); void (*ExceptionClear)(JNIEnv*); void (*FatalError)(JNIEnv*, const char*);
In addition, there is a function and they are not put together:
jboolean (*ExceptionCheck)(JNIEnv*);
We can tell from the name that the function used to detect the occurrence of an exception is:
- (Exceptioncheck) (jnienv);
- (exceptionoccurred) (jnienv);
The exceptions to be cleaned are:
- (exceptionclear) (jnienv);
Used to run out of exceptions are:
- (Throw) (jnienv, jthrowable);
- (thrownew) (jnienv , jclass, const char *);
- (fatalerror) (jnienv, const char*);
Here is a brief introduction to the above functions:
1> Exceptioncheck: Checks If an exception has occurred and returns Jni_true if an exception is returned Jni_false
2> exceptionoccurred: Checks If an exception has occurred and returns a reference to the exception with an exception, otherwise null is returned
3> exceptiondescribe: Stack information for printing exceptions
4> exceptionclear: Clear Exception stack information
5> thrownew: Triggers an exception on the current thread and customizes output exception information
6> Throw: Discards an existing exception object, triggering a new exception on the current thread
7> FatalError: Fatal exception for outputting an exception message and terminating the current VM instance (that is, exiting the program)
Test exception
Based on the above summary, we write the following function test code:
Native calls the method in Java, the method in Java throws an exception, we detect the exception in native, we detect the exception thrown in the native, and clean up the exception.
C code
void Native_catchexception (jnienv *env, Jobject obj) {jthrowable exc; JclassCLS =(*env)->getobjectclass (env, obj); JmethodidMID =(*env)->getmethodid (env, CLS,"Callbackexception","() V");if (mid = = NULL) {Return }(*env)->callvoidmethod (env, obj, mid);EXC =(*env)->exceptionoccurred (env);if (exc) {Jclass newexccls;(*env)->exceptiondescribe (env); (*env)->exceptionclear (env); newexccls = (*env)->findclass (env,"java/lang/illegalargumentexception"); if (newexccls = = NULL) {/ * Unable to find the exception class, give up. */ return;} (*env)->thrownew (env, NEWEXCCLS, "thrown from C Code");}} Static Jninativemethod gmethods[] = {... {"exception","() V", (void *) native_catchexception},};
See the previous section for additional sections of the code.
Java code
ProtectedvoidOnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (R.layout.activity_main); TextView = (TextView) Findviewbyid (R.id.text); try {exception ();} catch (Exception e) {System.out.println ("in java:\n\t" + E);}} private native void exception () throws illegalargumentexception; private void callbackexception () throws NullPointerException { throw new NullPointerException ("mainactivity.callbackexception");}
Output
09-2610:58:50.01223934-23934/Com. Jinwei. Jnitesthello W/system. Err:java. lang. Nullpointerexception:mainactivity. callbackexception09-2610:58:50.01223934-23934/Com. Jinwei. Jnitesthello W/system. err:atCom. Jinwei. Jnitesthello. Mainactivity. Callbackexception (mainactivity. Java:24)09-2610:58:50.01223934-23934/Com. Jinwei. Jnitesthello W/system. err:atCom. Jinwei. Jnitesthello. Mainactivity. Exception (Native Method)09-2610:58:50.01223934-23934/Com. Jinwei. Jnitesthello W/system. err:atCom. Jinwei. Jnitesthello. Mainactivity. OnCreate (mainactivity. Java:32)09-2610:58:50.01323934-23934/Com. Jinwei. Jnitesthello W/system. Err:at Android. App. Activity. Performcreate (Activity. Java:6299)09-2610:58:50.01323934-23934/Com. Jinwei. Jnitesthello W/system. Err:at Android. App. Instrumentation. Callactivityoncreate (instrumentation. Java:1107)09-2610:58:50.01323934-23934/Com. Jinwei. Jnitesthello W/system. Err:at Android. App. Activitythread. performlaunchactivity (Activitythread. Java:2369)09-2610:58:50.01323934-23934/Com. Jinwei. Jnitesthello W/system. Err:at Android. App. Activitythread. handlelaunchactivity (Activitythread. Java:2476)09-2610:58:50.01323934-23934/Com. Jinwei. Jnitesthello W/system. Err:at Android. App. ACTIVITYTHREAD.-WRAP11 (Activitythread. Java)09-2610:58:50.01323934-23934/Com. Jinwei. Jnitesthello W/system. Err:at Android. App. Activitythread$h. Handlemessage (Activitythread. Java:1344)09-2610:58:50.01323934-23934/Com. Jinwei. Jnitesthello W/system. Err:at Android-op. Handler. DispatchMessage (Handler. Java:102)09-2610:58:50.01323934-23934/Com. Jinwei. Jnitesthello W/system. Err:at Android-op. Looper. Loop (Looper. Java:148)09-2610:58:50.01323934-23934/Com. Jinwei. Jnitesthello W/system. Err:at Android. App. Activitythread. Main (Activitythread. Java:5417)09-2610:58:50.01323934-23934/Com. Jinwei. Jnitesthello W/system. err:at Java. lang. reflect. Method. Invoke (Native Method)09-2610:58:50.01323934-23934/Com. Jinwei. Jnitesthello W/system. err:atCom. Android. Internal-op. Zygoteinit$methodandargscaller. Run (Zygoteinit. Java:731)09-2610:58:50.01323934-23934/Com. Jinwei. Jnitesthello W/system. err:atCom. Android. Internal-op. Zygoteinit. Main (Zygoteinit. Java:621)09-2610:58:50.013 23934- 23934/com.jinwei.jnitesthello i/system.out: in java:09-26 10:58:50.013 23934-23934/com.jinwei.jnitesthello I/system .out:java.lang . Illegalargumentexception:thrown from C code
From the output we see the C code used: (*ENV)->thrownew (env, NEWEXCCLS, "thrown from C code"), this line of code ran out of the exception. The exception handler in Java then prints the stack's information.
Tool functions
It is classic to throw exceptions in JNI: Find the Exception class and call Thrownew to throw it; So, you can write a tool function.
voidJNU_ThrowByName(JNIEnv *env, const char *name, const char *msg){ jclass cls = (*env)->FindClass(env, name); /* if cls is NULL, an exception has already been thrown */ if (cls != NULL) { (*env)->ThrowNew(env, cls, msg); } /* free the local ref */ (*env)->DeleteLocalRef(env, cls);}
Android JNI/NDK Programming Five: JNI exception handling