APP 稳定性的维度
app 稳定一般指的是 app 能正常运行, app 不能正常运行的情况分为两大类,分别是 Crash 和 ANR。
Crash:运行过程中发生的错误,是无法避免的。
ANR:应用再运行时,由于无法在规定的时间段内响应完,系统做出的一个操作。
如何治理 Crash
应用发生 Crash 是由于应用在运行时,应用产生了一个未处理的异常(就是没有被 try catch 捕获的异常)。这会导致 app 无法正常运行。
如果需要解决的话,就需要知道这个未处理的异常是在哪里产生的,一般是通过分析未处理的异常的方法调用堆栈来解决问题。
Android APP 可以分为 2 层,Java 层和 Native 层。所以如何捕获需要分开说。
Java 层获取未处理的异常的调用堆栈
这个需要了解 Java 虚拟机是如何把一个未捕获的异常报上来的。
未捕获的异常,会沿着方法的调用链依次上抛,调用到Thread的dispatchUncaughtException 方法。
//Thread.java
public interface UncaughtExceptionHandler {
void uncaughtException(Thread t, Throwable e);
}
/**
* Dispatch an uncaught exception to the handler. This method is
* intended to be called only by the runtime and by tests.
*
* @hide
*/
// Android-changed: Make dispatchUncaughtException() public, for use by tests.
public final void dispatchUncaughtException(Throwable e) {
// BEGIN Android-added: uncaughtExceptionPreHandler for use by platform.
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
}
}
// END Android-added: uncaughtExceptionPreHandler for use by platform.
getUncaughtExceptionHandler().uncaughtException(this, e);
}
public UncaughtExceptionHandler getUncaughtExceptionHandler() {
return uncaughtExceptionHandler != null ?
uncaughtExceptionHandler : group;
}
//ThreadGroup.java
public void uncaughtException(Thread t, Throwable e) {
if (parent != null) {
// 递归调用,可以忽略
parent.uncaughtException(t, e);
} else {
// 交给了 Thread.getDefaultUncaughtExceptionHandler() 来处理未捕获的异常
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);
}
}
}
查阅代码发现,发现 ThreadGroup 最终会给 Thread 的 defaultUncaughtExceptionHandler 处理。
private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler;
上面的代码显示:Thread 的 defaultUncaughtExceptionHandler 是 Thread 类的一个静态变量。
看到这里,如何捕获 Java 层未处理的异常就很清晰了,给 Thread 设置一