Android官方:https://developer.android.com/training/articles/perf-jni
有个头疼的问题,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();//清除异常
}