1. UncaughtExceptionHandler简介
网上搜索Android崩溃处理之类的,能看到很多关于UncaughtExceptionHandler的文章,包括常用的一些处理方式。
但是,只有很小一部分文章提到这个问题:UncauchtExceptionHandler的对象是线程,而不是进程或app。
2. UncaughtExceptionHandler解析
/**
* Interface for handlers invoked when a <strong><span style="color:#ff0000;"><tt>Thread</tt> abruptly</span></strong>
* <strong><span style="color:#ff0000;">terminates</span></strong> due to an uncaught exception.
* <p>When a thread is about to terminate due to an uncaught exception
* the Java Virtual Machine will query the thread for its
* <tt>UncaughtExceptionHandler</tt> using
* {@link #getUncaughtExceptionHandler} and will invoke the handler's
* <tt>uncaughtException</tt> method, passing the thread and the
* exception as arguments.
* If a thread has not had its <tt>UncaughtExceptionHandler</tt>
* explicitly set, then its <tt>ThreadGroup</tt> object acts as its
* <tt>UncaughtExceptionHandler</tt>. If the <tt>ThreadGroup</tt> object
* has no
* special requirements for dealing with the exception, it can forward
* the invocation to the {@linkplain #getDefaultUncaughtExceptionHandler
* default uncaught exception handler}.
*
* @see #setDefaultUncaughtExceptionHandler
* @see #setUncaughtExceptionHandler
* @see ThreadGroup#uncaughtException
* @since 1.5
*/
public interface UncaughtExceptionHandler {
/**
* Method invoked when <strong><span style="color:#ff0000;">the given thread</span></strong> 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);
}
从源码中可以看出,UncaughtExceptionHandler自JDK1.5开始可用,处理对象为相关线程
3. UncaughtExceptionHandler使用
这里只介绍使用框架,不引入业务逻辑:
CrashHandler的单例模式简单实现:(单例模式选了一种最易理解的写法,因为单例模式不在这篇博客的讨论范围之内)
public class CrashHandler implements UncaughtExceptionHandler {
// Singleton Instance
private static CrashHandler gInstance = null;
private CrashHandler() {
}
private static class InstanceHolder {
static CrashHandler instance = new CrashHandler();
}
public static CrashHandler getInstance() {
if (gInstance == null) {
gInstance = new CrashHandler();
}
return InstanceHolder.instance;
}
public void init() {
Thread.setDefaultUncaughtExceptionHandler(this);
}
@Override
public void uncaughtException(Thread t, Throwable e) {
// TODO
}
}
MyApplication绑定UI主线程与CrashHandler。
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
CrashHandler.getInstance().init();
}
}
4. 注意
1. 如果CrashHandler中未调用Systen.exit(int)之类的方法,整个app就会僵死:不会崩溃,但对于任何触摸等动作也无响应。
2. 如果把以下这段异常代码加入UI线程,CrashHandler可以捕获java.lang.ArithmeticException: divide by zero;
但是,如果把这段异常代码加入非UI线程中,CrashHandler无法捕获异常。但是,app还是会崩溃。
int x = 1/0;