首先,Java中定义异常的顶级类是 Throwable
,它是 Error
类和 Exception
类的父类。只有继承于 Throwable
类或其子类的对象才能被Java虚拟机或者Java的 throw
语句抛出。同样,也只有这样的类才能作为被 catch
语句捕获的参数类型。
Java中的异常可以分类两类:
- 一类是检测异常(
checked exception
),又称作编译时异常,它必须在编译阶段处理,一般使用try...catch
来捕获处理,或者用throws
关键字声明。 - 另一类是非检测异常(
unchecked exception
),又称作运行时异常,在程序运行时满足某些条件才会触发。运行时异常包括RuntimeException
和Error
。Error一般是比较严重的错误,无需捕获。
Java为我们提供了一个全局的异常捕获处理器:位于Thread类的 defaultUncaughtExceptionHandler
。当然,Thread类也提供了方法让我们可以替换这个默认的异常捕获处理器。
定义自己的异常处理器
定义自己的异常处理器只需继承 Thread.UncaughtExceptionHandler
接口,并实现它的 uncaughtException(@NonNull Thread t, @NonNull Throwable e)
方法。
如下:
public class CrashHandler implements Thread.UncaughtExceptionHandler {
private Context mContext;
//系统默认的异常处理器
private Thread.UncaughtExceptionHandler defaultExceptionHandler;
public CrashHandler(Context context) {
mContext = context.getApplicationContext();
defaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
}
@Override
public void uncaughtException(@NonNull Thread t, @NonNull Throwable e) {
//handleThrowable方法用来处理和拼装异常信息,可以保存到本地或者上传到服务器都行
boolean interceptor = handleThrowable(e);
//如果不拦截,自己处理后交由系统默认的处理器来处理;
//一般来说不要拦截比较好,除非想屏蔽默认处理器的行为;
if(!interceptor){
defaultExceptionHandler.uncaughtException(t, e);
}
}
}
替换默认的异常处理器
替换很简单,只需调用Thread类提供的方法就行:
Thread.setDefaultUncaughtExceptionHandler(new CrashHandler(this));
一般来说可以写在Application的 onCreate
方法中。
总之就是这么简单。一般的第三方异常上报SDK,比如
Firebase Crashlytics
,大体上也是这样实现的。