1. 程式人生 > >Jni C/C++執行時遇到異常怎麼辦?捕獲與丟擲

Jni C/C++執行時遇到異常怎麼辦?捕獲與丟擲

有個頭疼的問題,Jni C/C++遇到問題閃退怎麼辦?有辦法,我們可以在異常發生後通過判斷清除異常解決,保持程式及時反應處理。

比如:

package crash;

import java.security.NoSuchAlgorithmException;

public class DogUtils {
    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

    public static native void test();

    public static void test1() throws NoSuchAlgorithmException {
        throw new NoSuchAlgorithmException("發生錯誤");
    }

    public static native void throwException();

}

在Jni中呼叫DogUtils類的test1方法,正常來講程式一定閃退。但通過ExceptionClear清除異常後,程式會繼續執行,是不是沒想到位元組碼還有這樣的優點。
extern "C" JNIEXPORT void JNICALL
Java_crash_DogUtils_test(JNIEnv *env,
                                        jobject /* this */) {
    jclass jcls = (env)->FindClass("crash/DogUtils");

    jmethodID testMethod1 = (env)->GetStaticMethodID(jcls, "test1", "()V");

    if (env->ExceptionCheck()) {
        env->ExceptionClear();//清除異常
        LOGD("GetStaticMethodID時發生錯誤");
    }

    (env)->CallStaticVoidMethod(jcls, testMethod1);

    if (env->ExceptionCheck()) {
        env->ExceptionClear();//清除異常
        LOGD("CallStaticVoidMethod時發生錯誤");
    }

    //呼叫DogUtils類中不存在的test2方法
    jmethodID testMethod2 = (env)->GetStaticMethodID(jcls, "test2", "()V");

    if (env->ExceptionCheck()) {
        env->ExceptionClear();//清除異常
        LOGD("獲取test2時發生錯誤");
    }

    if (testMethod2 == NULL) {
        LOGD("test2方法不存在");
        return;
    }

    (env)->CallStaticVoidMethod(jcls, testMethod2);

    if (env->ExceptionCheck()) {
        env->ExceptionClear();//清除異常
        LOGD("呼叫test2時發生錯誤");
    }

}

在Java層面呼叫DogUtils類的throwException方法,也不會影響程式執行,因為及時清除了這個異常:
extern "C" JNIEXPORT void JNICALL
Java_crash_DogUtils_throwException(JNIEnv *env,
                                                  jobject /* this */) {
    env->ThrowNew(env->FindClass("java/lang/Exception"), "這裡出現了異常");
    env->ExceptionClear();//清除異常
}