其实这个算是java的知识,在程序抛出无法捕捉的异常时,会触发Thread中的
defaultUncaughtExceptionHandler
的uncaughtException
方法,UncaughtExceptionHandler
就是下面这个接口
public interface UncaughtExceptionHandler {
/**
* Method invoked when the given thread terminates due to the
* given uncaught exception.
* <p>Any exception thrown by this method will be ignored by the
* Java Virtual Machine.
* @param t the thread
* @param e the exception
*/
void uncaughtException(Thread t, Throwable e);
}
当然Android中系统自己实现了这个接口,就是下面的
KillApplicationHandler
/**
* Handle application death from an uncaught exception. The framework
* catches these for the main threads, so this should only matter for
* threads created by applications. Before this method runs,
* {@link LoggingHandler} will already have logged details.
*/
private static class KillApplicationHandler implements Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e) {
try {
// Don't re-enter -- avoid infinite loops if crash-reporting crashes.
if (mCrashing) return;
mCrashing = true;
// Try to end profiling. If a profiler is running at this point, and we kill the
// process (below), the in-memory buffer will be lost. So try to stop, which will
// flush the buffer. (This makes method trace profiling useful to debug crashes.)
if (ActivityThread.currentActivityThread() != null) {
ActivityThread.currentActivityThread().stopProfiling();
}
// Bring up crash dialog, wait for it to be dismissed
ActivityManager.getService().handleApplicationCrash(
mApplicationObject, new ApplicationErrorReport.ParcelableCrashInfo(e));
} catch (Throwable t2) {
if (t2 instanceof DeadObjectException) {
// System process is dead; ignore
} else {
try {
Clog_e(TAG, "Error reporting crash", t2);
} catch (Throwable t3) {
// Even Clog_e() fails! Oh well.
}
}
} finally {
// Try everything to make sure this process goes away.
Process.killProcess(Process.myPid());
System.exit(10);
}
}
}
在App启动时,App会执行这个语句
Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler());
这样Android就完全接管了不可捕捉的异常,也就是Crash,可以看到,Android的处理到最后是把当前进程给结束了,这就是Crash后App会闪退的原因了。
finally {
// Try everything to make sure this process goes away.
Process.killProcess(Process.myPid());
System.exit(10);
}
因此我们要自己处理Crash的话也需要自己实现一个
UncaughtExceptionHandler
,然后在Application类中进行设置
class App : Application() {
override fun onCreate() {
super.onCreate()
Thread.setDefaultUncaughtExceptionHandler(MyUncaughtExceptionHandler());
}
这样做的好处有很多,比如可以在这里将异常上传至服务器,也可以给用户有好的提示,或者是掩盖错误,直接返回到出错之前的页面。
网友评论