2012-01-08 8 views
10

Czy istnieje sposób na otrzymanie powiadomienia, gdy aplikacja uruchomi ANR (Application Not Responding)? Podobne do domyślnego programu obsługi wyjątków?Posłuchaj i odpowiedz na ANR?

W oczekiwaniu na odpowiedź "co byś zrobił", wystarczy zalogować. Nie "robić" niczego.

+3

@ DarrenFaith Dude. O czym mówisz? Akceptuję zadowalające odpowiedzi. Jeśli ktoś odpowie, ale tak naprawdę nie odpowiada na pytanie, nie akceptuję ich. Większość moich pytań jest * naprawdę * trudna lub nie ma odpowiedzi. Zwykle do czasu, kiedy pytam, bardzo dużo szukałem, a jeśli to jest pytanie na Androida i nie mogę znaleźć odpowiedzi samemu, to będzie to * naprawdę trudne * pytanie. Mój przedstawiciel 2K odpowiada na pytania. Jeśli moja aplikacja jest dostępna na rynku, widzę zamrożenie. Ohyda. Chcę je złapać. –

+1

@WarrenFaith PS. Jeśli możesz mi powiedzieć, jak złapać ANR, obiecuję, że twoja odpowiedź zostanie przyjęta. Sądząc po twoim "Jeśli twoja aplikacja jest na rynku ...", nie wiesz jak, więc jeśli odpowiesz, nie będę" akceptował "tego, ponieważ nie jest to odpowiedź, czy raczej powinienem zaakceptować to tylko dlatego, że to napisałeś? –

+2

@WarrenFaith PPS , jeśli odpowiedź brzmi "nie możesz tego zrobić", powinieneś cytować źródło z linkiem, inaczej jest to tylko domysły –

Odpowiedz

1

Nie. W przeciwieństwie do wyjątków występujących w maszynie wirtualnej procesu, które można przechwycić, ANR jest generowany przez systemowy system nadzorujący poza VM. Google oferuje info on triggers and avoidance

+0

Naprawdę uważam, że nie ma mowy aby to zrobić, co jest dość frustrujące. Może (może) zrobić coś specjalnego z moim własnym API i wątkiem do złapania, ale to wydaje się dość hacky. –

0

można użyć usługi (najlepiej usługi na pierwszym planie), która nasłuchuje dzienników (za pomocą wątku), a jeśli jest dziennik wskazujący ANR, należy go obsłużyć.

oto mała próbka aplikacji, która powoduje ANR:

... 
findViewById(R.id.button).setOnClickListener(new OnClickListener() 
    { 
    @Override 
    public void onClick(final View v) 
     { 
     try 
     { 
     Thread.sleep(10000); 
     } 
     catch(final InterruptedException e) 
     { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     } 
     } 
    }); 
... 

Oto dziennik, który dostałem od LogCat kiedy mam ANR:

08-03 13:02:37.746: E/ActivityManager(158): ANR in com.example.anr (com.example.anr/.MainActivity) 
08-03 13:02:37.746: E/ActivityManager(158): Reason: keyDispatchingTimedOut 
08-03 13:02:37.746: E/ActivityManager(158): Load: 6.19/2.37/0.86 
08-03 13:02:37.746: E/ActivityManager(158): CPU usage from 5598ms to 0ms ago: 
08-03 13:02:37.746: E/ActivityManager(158): 2.6% 158/system_server: 2.5% user + 0.1% kernel/faults: 86 minor 
08-03 13:02:37.746: E/ActivityManager(158): 0.5% 298/com.android.phone: 0.3% user + 0.1% kernel/faults: 15 minor 
08-03 13:02:37.746: E/ActivityManager(158): 0% 35/rild: 0% user + 0% kernel 
08-03 13:02:37.746: E/ActivityManager(158): 4.6% TOTAL: 3.9% user + 0.6% kernel 
08-03 13:02:37.746: E/ActivityManager(158): CPU usage from 2029ms to 2654ms later: 
08-03 13:02:37.746: E/ActivityManager(158): 11% 158/system_server: 4.8% user + 6.4% kernel/faults: 2 minor 
08-03 13:02:37.746: E/ActivityManager(158):  11% 192/InputDispatcher: 4.8% user + 6.4% kernel 
08-03 13:02:37.746: E/ActivityManager(158):  1.6% 163/Compiler: 1.6% user + 0% kernel 
08-03 13:02:37.746: E/ActivityManager(158):  1.6% 193/InputReader: 0% user + 1.6% kernel 
08-03 13:02:37.746: E/ActivityManager(158): 18% TOTAL: 9.3% user + 9.3% kernel 

tak, tak myślę to jest możliwe.

+0

Nie będzie to możliwe jak z Jelly Bean, ponieważ nie będziesz w stanie odczytać dzienników z innych procesów lub systemu operacyjnego. Poza tym czytanie dzienników nie jest częścią zestawu SDK systemu Android. – CommonsWare

+0

correct.since Nie mam JB, nie widzę, czy są jakieś obejścia tego problemu. powiedzieli w Google IO, że chociaż teraz to nie zadziała, można przeczytać dzienniki własnej aplikacji, więc nie wiem, czy takie rzeczy są uważane za znajdujące się wewnątrz aplikacji (chyba nie) .neway, to rozwiązanie jest obejściem od samego początku. Powinno działać na około 99% urządzeń. –

+0

Mam inny pomysł. Publikuje w sekcji odpowiedzi. –

5

Myślałem o tym całkiem sporo. Możesz może zrobić następujące, choć jest dość ciężko wręczył. Wypisz ANR to nici plik do katalogu ogólnie czytelnej:

/data/anr/traces.txt

Można mieć usługę, w innym procesie, ankiety, które okresowo złożenia. Jeśli data zmieni się, a twoja aplikacja jest na górze, prawdopodobnie masz zdarzenie ANR.

Nie jestem jednak w 100% pewien formatu pliku.

+0

To jest moja ulubiona odpowiedź. Muszę to wypróbować. Nie wiesz, jaki jest format pliku: będzie on zawierał nazwę pakietu aplikacji, dzięki czemu możesz upewnić się, że jest to Twoja aplikacja, która go wygenerowała. Zastanawiam się jednak, czy obserwatorzy systemu plików będą działać na tym pliku. Następnie przy każdej zmianie możesz sprawdzić, czy zawiera ona nazwę twojego pakietu. Można również sprawdzić na początku aplikacji, aby sprawdzić, czy aplikacja została zabita przez użytkownika po ANR. – 3c71

3

Ponieważ system watchdog nie ostrzega aplikacji, sama aplikacja może mieć swój własny watchdog. Kroki są proste, wystarczy uruchomić wątku, że pętle w następujący sposób:

  1. Schedule mały kod do uruchomienia na wątku UI jak najszybciej.
  2. Poczekaj na X sekund (ty decydujesz).
  3. Sprawdź, czy kod został uruchomiony: jeśli tak, wróć do 1
  4. Jeśli kod nie został uruchomiony, oznacza to, że wątek interfejsu użytkownika został zablokowany przez co najmniej X sekund, zgłasza wyjątek z wątkiem interfejsu użytkownika stos śledzenia

Napisałem a small library that does exactly that i używam go z ACRA.

Mam nadzieję, że pomoże;)

Powiązane problemy