Я просто хотел рассказать о своем опыте.Я использую решение, предложенное 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 ()