2013-04-08 3 views
10

У меня есть простая установка: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. Ситуация такова:

  1. Я выполняю код, который намеренно бросает NullPointerException;
  2. CrashHandler перехватывает его и создает notification (который показан);
  3. Android НЕ показывает никаких сообщений (например, нет «Application crashed», который должен быть видимым);
  4. MainActivity заморожен;
  5. Если пользователь нажимает на уведомление для запуска 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 сразу после создания уведомления, приложение сразу же прекратит работу и уведомление будет работать отлично (к сожалению, я не могу пойти с этим решением на производстве).

У меня есть два вопроса:

  1. Почему в OnClickListener.onClickNullPointer exception не вызывает приложение к краху, а не замораживанием вместе с операционной системой и предотвращения других видов деятельности от начала?
  2. Что делать, чтобы избежать этого вообще или, по крайней мере, как сделать CrashActivity начать в этих условиях?
+0

Я думаю, вы должны опубликовать часть своего кода из ** onClick **, чтобы мы могли понять. –

ответ

0

Не видя своего кода, вы должны отладить у вас класс CrashHandler. JVM будет игнорировать все исключения в этом

void uncaughtException(Thread t, Throwable e) 

«Любое исключении, устроенном этот метод будет проигнорирован виртуальной машиной Java.» (JavaDoc).

Я не говорю, что это ответ, но это может быть ответ, если этот метод исключает.