前言
看到这个问题,马上就可以回答出来:因为抛出异常就会 crash。
那么为什么抛出异常就会 crash 呢?
有没有办法不让 App crash 呢?
接下来我们进入正题吧
先探讨一下第一个问题吧:为什么抛出异常就会 crash。
首先我们看下线程中抛出异常以后的处理逻辑吧:
一旦代码抛出异常,并且我们没有捕捉的情况下,JVM 会调用 Thread 的 dispatchUncaughtException 方法。
public final void dispatchUncaughtException(Throwable e) {
Thread.UncaughtExceptionHandler initialUeh =
Thread.getUncaughtExceptionPreHandler();
if (initialUeh != null) {
try {
initialUeh.uncaughtException(this, e);
} catch (RuntimeException | Error ignored) {
// Throwables thrown by the initial handler are ignored
}
}
//这里会获取对应的 UncaughtExceptionHandler 对象,然后调用对应的 uncaughtException 方法
getUncaughtExceptionHandler().uncaughtException(this, e);
}
public UncaughtExceptionHandler getUncaughtExceptionHandler() {
//可以看到当 uncaughtExceptionHandler 没有赋值的时候,会返回 ThreadGroup 对象
return uncaughtExceptionHandler != null ?
uncaughtExceptionHandler : group;
}
看上述代码,如果 App 中并没有设置 uncaughtExceptionHandler 对象,那么会执行 ThreadGroup的uncaughtException 方法:
public void uncaughtException(Thread t, Throwable e) {
if (parent != null) {
parent.uncaughtException(t, e);
} else {
Thread.UncaughtExceptionHandler ueh =
Thread.getDefaultUncaughtExceptionHandler();
if (ueh != null) {
ueh.uncaughtException(t, e);
} else if (!(e instanceof ThreadDeath)) {
System.err.print("Exception in thread \""
+ t.getName() + "\" ");
e.printStackTrace(System.err);
}
}
}
然后调用 Thread.getDefaultUncaughtExceptionHandler() 获取默认的 UncaughtExceptionHandler ,然后调用 uncaughtException 方法,既然名字是默认的 uncaughtExceptionHandler 对象,那么必然有初始化的地方,这就需要从系统初始化开始说起,不过初始化流程特别复杂,也不是本篇重点,所以就直接从 RuntimeInit 的 main 方法开始吧。
public static final void main(String[] argv) {
enableDdms();
if (argv.length == 2 && argv[1].equals("application")) {
if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application");
redirectLogStreams();
} else {
if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting tool");
}
commonInit();
/*
* Now that we're running in interpreted code, call back into native code
* to run the system.
*/
nativeFinishInit();
if (DEBUG) Slog.d(