2013-04-08 15 views
10

mam prostą konfigurację:Android zamarza, gdy istnieje NullPointerException w OnClickListener.onClick (inne zadania nie można uruchomić)

  • CrashHandler - klasy, która implementuje Thread.UncaughtExceptionHandler;
  • CrashActivity - działanie, które może wysyłać raporty użytkowników;
  • MainActivity - główna aplikacja, z którą użytkownik powinien wchodzić w interakcje.

Gdy jest przechwycony wyjątek w MainActivity lub którykolwiek To gwintów CrashHandler Przechwytuje i tworzy powiadomienia z zamiarem rozpoczęcia 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); 

W Średni czas Android pokazach wiadomość "Zgłoszenie aplikacji", użytkownik kliknie przycisk OK, aplikacja zostanie zamknięta, a następnie użytkownik może kliknąć ikonę notification. Po kliknięciu przycisku notification rozpoczyna się i pokazuje CrashActivity.

Kod ten działał przez długi czas w wielu różnych sytuacjach (awarie głównego wątku, awaria w handler, awaria na tle thread ...). Jednak niedawno odkryłem, że NIE DZIAŁA, jeśli wyjątek został zgłoszony w metodzie OnClickListener.onClick w detektorze dołączonym do button w . Sytuacja wygląda następująco:

  1. Wykonuję kod, który celowo rzuca NullPointerException;
  2. CrashHandler przechwytuje i tworzy notification (co pokazano);
  3. Android NIE wyświetla żadnych komunikatów (na przykład nie ma "aplikacji zawieszonej", co powinno być widoczne);
  4. Urządzenie MainActivity jest zamrożone;
  5. JEŻELI użytkownik kliknie powiadomienie, aby uruchomić CrashActivity, pojawi się czarny ekran i wszystko zawiesza się (pożądana aktywność nie jest pokazana).

Logcat pokazuje, że nie jest to czas oczekiwania na uruchomienie nawet przed OnCreate lub którykolwiek z mojego kodu:

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} 
  • Jeśli przed kliknięciem notification zabiję aplikację z ADB, że notification działa doskonale .
  • Jeśli przed kliknięciem notification robię kilka kliknięć i gesty na zamarzniętym aplikacji, po kilku sekundach pojawia się komunikat o 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 
    
  • Jeśli kliknę „tak, zabij go” a następnie kliknij notification, działa idealnie.

  • Jeśli dodam System.exit (-1) w CrashHandler zaraz po utworzeniu powiadomienia, aplikacja natychmiast wychodzi i powiadomienie działa idealnie (niestety, nie mogę przejść z tym rozwiązaniem w produkcji).

Mam dwa pytania:

  1. Dlaczego NullPointer exception w OnClickListener.onClick nie powoduje awarię aplikacji, zamiast zamrażania go wraz z systemem operacyjnym i zapobiegania innych czynności przed uruchomieniem?
  2. Co należy zrobić, aby go uniknąć w ogóle, a przynajmniej jak wprowadzić CrashActivity w tych warunkach?
+0

Myślę, że należy opublikować część kodu z ** onClick **, abyśmy mogli zrozumieć. –

Odpowiedz

0

Nie widząc kodu, powinieneś zdebugować klasę CrashHandler. JVM zignoruje wszystkie wyjątki w tym "Wszelkie wyjątki wygenerowane przez tę metodę zostaną zignorowane przez wirtualną maszynę Java." (JavaDoc).

Nie mówię, że to jest odpowiedź, ale możliwe, że odpowiedź, jeśli ta metoda wyklucza wyjątki.

Powiązane problemy