У меня есть простая установка:Android замирает, когда есть NullPointerException в OnClickListener.onClick (другие задачи не могут начать)
CrashHandler
- класс, который реализуетThread.UncaughtExceptionHandler
;CrashActivity
- деятельность, которая может отправлять отчеты пользователей;MainActivity
- основное приложение, с которым пользователь должен взаимодействовать.
Когда есть неперехваченное исключение в MainActivity
или любой из его нитей, то CrashHandler
перехватывает это и создает уведомление с намерением начать CrashActivity
:
Intent it = new Intent("CrashReporter" + SystemClock.currentThreadTimeMillis());
it.setClass(context, CrashActivity.class);
it.setFlags(it.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
В то же время показывает Android сообщение «сбой приложения», пользователь нажимает «ОК», приложение закрывается, а затем пользователь может нажать notification
. Если щелкнуть notification
, начнется и показывается CrashActivity
.
Этот код работает долгое время во многих ситуациях (авария на главной нити, авария в handler
, авария на фоне thread
...). Тем не менее, я недавно обнаружил, что он НЕ РАБОТАЕТ, если исключение выбрано в методе OnClickListener.onClick
в слушателе, прикрепленном к button
в MainActivity
. Ситуация такова:
- Я выполняю код, который намеренно бросает
NullPointerException
; CrashHandler
перехватывает его и создаетnotification
(который показан);- Android НЕ показывает никаких сообщений (например, нет «Application crashed», который должен быть видимым);
MainActivity
заморожен;- Если пользователь нажимает на уведомление для запуска
CrashActivity
, отображается черный экран и все зависает (желаемая активность не отображается).
Logcat
показывает, что есть тайм-аут запуска, еще до OnCreate
или какой-либо из моего кода:
I/ActivityManager(11826): START u0 {act=CrashHandler1196 flg=0x14000000 cmp=mycompany.myapp/.CrashActivity bnds=[0,102][720,230] (has extras)} from pid -1
W/KeyguardViewMediator(11826): verifyUnlock called when not externally disabled
W/ActivityManager(11826): Activity pause timeout for ActivityRecord{41f4d988 u0 mycompany.myapp/.MainActivity}
W/ActivityManager(11826): Launch timeout has expired, giving up wake lock!
W/ActivityManager(11826): Activity idle timeout for ActivityRecord{4225eeb8 u0 mycompany.myapp/.CrashActivity}
- Если перед нажатием на
notification
я убить приложение изADB
, чтоnotification
работает отлично , Если перед нажатием на
notification
я сделать несколько кликов и жесты на замерзшем приложение, через несколько секунд я получаю сообщение обANR
:E/ActivityManager(11826): ANR in mycompany.myapp (mycompany.myapp/.MainActivity) E/ActivityManager(11826): Reason: keyDispatchingTimedOut E/ActivityManager(11826): Load: 0.63/0.57/0.49
Если я нажимаю «да, убить его», а затем нажмите
notification
, он отлично работает.- Если я добавлю
System.exit
(-1) вCrashHandler
сразу после создания уведомления, приложение сразу же прекратит работу и уведомление будет работать отлично (к сожалению, я не могу пойти с этим решением на производстве).
У меня есть два вопроса:
- Почему в
OnClickListener.onClick
NullPointer exception
не вызывает приложение к краху, а не замораживанием вместе с операционной системой и предотвращения других видов деятельности от начала? - Что делать, чтобы избежать этого вообще или, по крайней мере, как сделать
CrashActivity
начать в этих условиях?
Я думаю, вы должны опубликовать часть своего кода из ** onClick **, чтобы мы могли понять. –