我只想指出到目前为止的经验。我正在使用https://stackoverflow.com/a/26560727/2737240建议的解决方案,以在将控制权交给默认异常处理程序之前将异常刷新到我的日志文件中。
但是,我的结构如下所示:
BaseActivity
|
_______________________
| | |
Activity A Activity B Activity C
final Thread.UncaughtExceptionHandler defaultEH = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable e) {
handleUncaughtException(thread, e, defaultEH);
}
});
在其中handleUncaughtException(thread, e, defaultEH);写入日志并将调用移交给原始的UncaughtExceptionHandler。
因此,使用此代码会发生以下情况:
活动A被实例化
现在,新的默认异常处理程序(DEH)是我的日志处理程序+旧的DEH
活动B被实例化
现在,新DEH是我的日志处理程序+旧DEH(日志处理程序+原始DEH)
活动C被实例化
现在,新的DEH是我的日志处理程序+旧的DEH(日志处理程序+日志处理程序+原始DEH)
因此,这条链无限增长,从而导致两个问题:
指定的自定义代码(在我的情况下,将其写入日志文件)将被多次调用,这不是所需的操作。
即使活动完成后,defaultEh的引用也保留在堆中,因为引用链使用了它,因此可能发生的最坏的情况是内存不足异常。
因此,我又添加了一点东西来最终使这项工作毫无问题:
private static boolean customExceptionHandlerAttached = false;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(!customExceptionHandlerAttached) {
final Thread.UncaughtExceptionHandler defaultEH = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable e) {
handleUncaughtException(thread, e, defaultEH);
}
});
customExceptionHandlerAttached = true;
}
}
使用此解决方案,我们可以确保:
为我们所需的操作添加自定义异常处理程序
确保此操作仅触发一次
允许垃圾回收器通过调用finish()完全处置我们的活动