Я хочу, чтобы мое приложение останавливалось, когда ACRA обнаруживает и сообщает о неперехваченном исключении — нормальное поведение ACRA. Это не работает, когда исключение происходит в действии, которое не является основным.
После борьбы с этим в моем реальном приложении я создал очень простое приложение, которое использует ACRA и позволяет мне вызвать исключение либо в основном действии, либо во втором, которое можно запустить из первого. Я тестирую с MinSDK 26. Приложение написано на Java и имеет достаточно кода только для создания этого теста.
Исключение в первом действии приводит к желаемому результату (как определено из logcat и экрана):
- При нажатии кнопки основное действие генерирует исключение
- ACRA перехватывает исключение:
- ACRA запускает очередной процесс подачи заявок
- первый процесс заканчивается
- второй процесс выполняет обработку ACRA
- второй процесс заканчивается
Однако повторный запуск, но за исключением второго действия (с первым все еще в стеке задач), приводит к:
- При нажатии кнопки основное действие запускает второе действие
- При нажатии кнопки второе действие генерирует исключение
- ACRA запускает очередной процесс подачи заявок
- Первый процесс заканчивается
- Процессы ACRA во втором процессе (также с использованием этой кодовой базы)
- тем временем Android запускает третий процесс - в этом проблема
- Второй процесс завершается
- Третий процесс отображает основной экран активности и ждет
Похоже, что происходит то, что Android обнаруживает, что в стеке осталась активность, и запускает новый процесс, чтобы перенести ее вперед.
Но ACRA должно остановить это.
Это проблема ACRA? В любом случае, есть идеи, как это предотвратить?
*ПРИМЕЧАНИЕ:
- В своих тестах я использую сенсорные события на нижней панели навигации для создания исключения деления на ноль.
- Порядок завершения ACRA и запуска третьего процесса, насколько я могу судить, не определен. Тоже, наверное, неактуально.
- Результаты теста получены из просмотра экрана и logcat. Важные события регистрируются с помощью класса Log.
Ниже приведен фрагмент основного действия, показывающий обработку кнопки и создание исключения. Второе действие аналогично.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Context context = this.getApplicationContext();
setContentView(R.layout.activity_main);
Log.i(MyApp.TAG, "MainActivity.onCreate() - pid:"+android.os.Process.myPid());
mTextMessage = findViewById(R.id.message);
BottomNavigationView navigation = findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener((item) -> {
switch (item.getItemId()) {
case R.id.navigation_home:
int i = 0;
Log.i(MyApp.TAG, "Throwing exception in main activity");
Log.i(MyApp.TAG, "This shouldn't show up" + 3 / i);
return true;
case R.id.navigation_dashboard:
Log.i(MyApp.TAG, "Starting Activity2");
startActivity(new Intent(context, Activity2.class));
return true;
case R.id.navigation_notifications:
mTextMessage.setText(R.string.title_notifications);
return true;
}
return false;
});