Jak uzyskać dzienniki awarii Androida?


155

Mam aplikację, której nie ma na rynku (podpisana certyfikatem debugowania), ale chciałbym uzyskać dane dziennika awarii za każdym razem, gdy moja aplikacja ulegnie awarii. Gdzie mogę znaleźć dziennik przyczyn awarii mojej aplikacji?

Odpowiedzi:


139

Jeśli Twoja aplikacja jest pobierana przez inne osoby i ulega awarii na urządzeniach zdalnych, możesz zajrzeć do biblioteki raportowania błędów Androida (o której mowa w tym poście SO ). Jeśli jest tylko na własnym urządzeniu lokalnym, możesz użyć. LogCat. Nawet jeśli urządzenie nie było podłączone do komputera hosta, gdy wystąpiła awaria, podłączenie urządzenia i wydanie adb logcatpolecenia spowoduje pobranie całej historii logcat (przynajmniej w zakresie, w jakim jest buforowany, co zwykle jest groszem danych dziennika, po prostu nie jest nieskończone). Czy któraś z tych opcji odpowiada na Twoje pytanie? Jeśli nie, czy możesz spróbować nieco dokładniej wyjaśnić, czego szukasz?


2
czy możesz szczegółowo opisać, jak używać polecenia adb logcat? Czy mogę to uruchomić w katalogu / SDK / tools? Czy są jakieś flagi, na które powinienem zwrócić uwagę? itp.
jesses.co.tt

2
@ jesses.co.tt Tak, po prostu uruchom adb logcatz dowolnego katalogu, w którym znajduje się adb. Alternatywnie możesz użyć narzędzi SDK zawartych we wtyczce Eclipse
Chris Thompson

2
Crashlytics to najlepsze oprogramowanie do zdalnego rejestrowania wyjątków, jakiego kiedykolwiek używałem. Znika we wszystkich moich aplikacjach, sprawdź to.
Jacksonkr

adb.exe znajduje się w $SDK_DIR/platform-tools/. Aby pokazać błąd:.\adb.exe logcat -v time *:E
Harun

53

Aby to zrobić, należy zaimplementować Thread.UncaughtExceptionHandlerinterfejs i przekazać go Thread.setDefaultUncaughtExceptionHandler()na początku swojej aktywności onCreate(). Oto klasa implementacji TopExceptionHandler.

public class TopExceptionHandler implements Thread.UncaughtExceptionHandler {
    private Thread.UncaughtExceptionHandler defaultUEH;
    private Activity app = null;

    public TopExceptionHandler(Activity app) {
        this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
        this.app = app;
    }

    public void uncaughtException(Thread t, Throwable e) {
        StackTraceElement[] arr = e.getStackTrace();
        String report = e.toString()+"\n\n";
        report += "--------- Stack trace ---------\n\n";
        for (int i=0; i<arr.length; i++) {
            report += "    "+arr[i].toString()+"\n";
        }
        report += "-------------------------------\n\n";

        // If the exception was thrown in a background thread inside
        // AsyncTask, then the actual exception can be found with getCause

        report += "--------- Cause ---------\n\n";
        Throwable cause = e.getCause();
        if(cause != null) {
            report += cause.toString() + "\n\n";
            arr = cause.getStackTrace();
            for (int i=0; i<arr.length; i++) {
                report += "    "+arr[i].toString()+"\n";
            }
        }
        report += "-------------------------------\n\n";

        try {
            FileOutputStream trace = app.openFileOutput("stack.trace", 
                                                        Context.MODE_PRIVATE);
            trace.write(report.getBytes());
            trace.close();
        } catch(IOException ioe) {
        // ...
        }

        defaultUEH.uncaughtException(t, e);
    }
}

Uwaga Zezwalamy na obsługę defaultUEH platformy Android.

W górnej części swojej aktywności zarejestruj wystąpienie powyższej klasy, takie jak:

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

Thread.setDefaultUncaughtExceptionHandler(new TopExceptionHandler(this));
...

Ten program obsługi zapisuje ślad w pliku. Przy ReaderScopenastępnym uruchomieniu wykrywa plik i pyta użytkownika, czy chce wysłać go e-mailem do programisty.

Aby wysłać ślad stosu pocztą e-mail, wykonaj następujący kod, aby spakować go w wiadomości e-mail.

try {
    BufferedReader reader = new BufferedReader(
        new InputStreamReader(ReaderScopeActivity.this.openFileInput("stack.trace")));
    while((line = reader.readLine()) != null) {
        trace += line+"\n";
    }
} catch(FileNotFoundException fnfe) {
    // ...
} catch(IOException ioe) {
    // ...
}

Intent sendIntent = new Intent(Intent.ACTION_SEND);
String subject = "Error report";
String body = "Mail this to appdeveloper@gmail.com: " + "\n" + trace + "\n";

sendIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"readerscope@altcanvas.com"});
sendIntent.putExtra(Intent.EXTRA_TEXT, body);
sendIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
sendIntent.setType("message/rfc822");

ReaderScopeActivity.this.startActivity(Intent.createChooser(sendIntent, "Title:"));

ReaderScopeActivity.this.deleteFile("stack.trace");

Możesz też użyć systemu raportowania błędów ACRA, po prostu dołącz plik ACRA.jar do bibliotek projektu i użyj poniższego fragmentu kodu przed deklaracją klasy aktywności programu uruchamiającego

@ReportsCrashes(formKey = "", mailTo = "abc@gmail.com;def@yahoo.com", mode = ReportingInteractionMode.SILENT) 

lub możesz spróbować z konsoli: -

adb logcat -b crash 

Czy linia nie będzie domyślnaUEH.uncaughtException (t, e); wywołać metodę uncaughtException () w nieskończoność?
Mickael Bergeron Néron

@ MickaelBergeronNéron nie - po prostu przekaże ten sam Throwable do obsługi najwyższego poziomu.
formatBCE


36

Możesz to wypróbować z poziomu konsoli:

adb logcat --buffer=crash 

Więcej informacji na temat tej opcji:

adb logcat --help

...

  -b <buffer>, --buffer=<buffer>         Request alternate ring buffer, 'main',
                  'system', 'radio', 'events', 'crash', 'default' or 'all'.
                  Multiple -b parameters or comma separated list of buffers are
                  allowed. Buffers interleaved. Default -b main,system,crash.

9

Jeśli używasz Eclipse, upewnij się, że używasz debugowania i nie uruchamiasz. Upewnij się, że jesteś w perspektywie debugowania (w prawym górnym rogu). Aby dziennik został wydrukowany, może być konieczne kilkakrotne naciśnięcie przycisku „Wznów” (F8). Dziennik awarii będzie znajdował się w oknie Logcat na dole - kliknij dwukrotnie, aby wyświetlić pełny ekran i przewiń w dół. Zobaczysz czerwony tekst błędów, ślad awarii będzie podobny do

09-04 21:35:15.228: ERROR/AndroidRuntime(778): Uncaught handler: thread main exiting due to uncaught exception
09-04 21:35:15.397: ERROR/AndroidRuntime(778): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.dazlious.android.helloworld/com.dazlious.android.helloworld.main}: java.lang.ArrayIndexOutOfBoundsException
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2268) 
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2284)
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at android.app.ActivityThread.access$1800(ActivityThread.java:112)
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1692)
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at android.os.Handler.dispatchMessage(Handler.java:99)
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at android.os.Looper.loop(Looper.java:123)
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at android.app.ActivityThread.main(ActivityThread.java:3948)
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at java.lang.reflect.Method.invokeNative(Native Method)
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at java.lang.reflect.Method.invoke(Method.java:521)
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:782)
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:540)
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at dalvik.system.NativeStart.main(Native Method)
09-04 21:35:15.397: ERROR/AndroidRuntime(778): Caused by: java.lang.ArrayIndexOutOfBoundsException
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at com.example.android.helloworld.main.onCreate(main.java:13)
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2231)
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     ... 11 more

Ważnymi częściami tego są

09-04 21:35:15.397: ERROR/AndroidRuntime(778): Caused by: java.lang.ArrayIndexOutOfBoundsException
09-04 21:35:15.397: ERROR/AndroidRuntime(778):     at com.example.android.helloworld.main.onCreate(main.java:13)

mówią nam, że był to wyjątek poza granicami tablicy w linii 13 pliku main.java w metodzie onCrate.


9

Możesz użyć Apphance. Jest to usługa wieloplatformowa (obecnie głównie Android, iOS z innymi platformami w drodze), która pozwala na zdalne debugowanie dowolnego urządzenia mobilnego (teraz Android, iOS - inne w fazie rozwoju). To znacznie więcej niż tylko crashlog, w rzeczywistości to znacznie więcej: logowanie, raportowanie problemów przez testerów, crashlogy. Integracja zajmuje około 5 minut. Obecnie możesz poprosić o dostęp do zamkniętej bety.

Zastrzeżenie: Jestem dyrektorem technicznym Polidea, firmy stojącej za Apphance i współtwórcą jej.

Aktualizacja: Apphance nie jest już zamkniętą wersją beta! Aktualizacja 2: Apphance jest dostępna w ramach oferty http://applause.com


2
Właśnie wypróbowałem wygląd i podoba mi się. Dokumentacja pominęła kluczowy punkt podczas integracji Apphance Lib z Twoją aplikacją; W przypadku najnowszej wersji Eclipse ADT należy umieścić plik apphance.jar w libskatalogu, zgodnie z wyjaśnieniem tej odpowiedzi. To zatwierdzenie github pokazuje zmiany, które musiałem wprowadzić w mojej aplikacji WorldMap, aby korzystać z apphance.
JohnnyLambada

@HohnnyLambada Dzięki za komentarz. Zaktualizowaliśmy dokumentację, aby było to jaśniejsze.
Piotr Duda

12
to nie powinno dostać tak wielu strzałek w górę, że kosztuje 10 razy więcej niż większość budżetów na rozwój (2500 USD miesięcznie!)
user26676

Wygląda na 404 w dniu tego komentarza.
DaveP

Poprawny. Już dawno został kupiony przez uTest, który następnie przemianował całą swoją ofertę (w tym funkcję Aphhance) na Applause. A więc teraz applause.com
Jarek Potiuk


4

Możesz użyć ACRA z tego . Włączając tę ​​bibliotekę do swoich projektów i konfigurując ją, możesz otrzymywać (na swój e-mail lub gdoc) ich raporty o awariach. Przepraszam za mój zły angielski.


4

Jeśli szukasz podstawowego narzędzia do raportowania awarii, wypróbuj crashlytics .

Jeśli potrzebujesz bardziej zaawansowanego narzędzia do raportowania, Checkout Gryphonet . Rejestruje wszystkie awarie, które wystąpiły, wraz z dokładną linią kodu, która spowodowała awarię, wraz z automatycznymi znacznikami, które pokazują kroki podjęte przez użytkownika przed awarią i nie tylko.

Powodzenia!



2

Stworzyłem tę bibliotekę, aby rozwiązać wszystkie Twoje problemy. Crash Reporter to przydatne narzędzie do przechwytywania wszystkich awarii i lokalnego logowania do urządzenia

Po prostu dodaj tę zależność i gotowe.

compile 'com.balsikandar.android:crashreporter:1.0.1'

Znajdź lokalnie wszystkie awarie w urządzeniu i napraw je w dogodnym dla siebie czasie. Awarie są zapisywane przy użyciu łatwego do śledzenia formatu daty i godziny. Dodatkowo zapewnia również API do przechwytywania zarejestrowanych wyjątków przy użyciu poniższej metody.

CrashRepoter.logException(Exception e)

Jaka jest klasa Java, której użyłeś do pobrania dzienników awarii urządzenia?
Xenolion

Interfejs Thread.UncaughtExceptionHandler służy do przechwytywania wszystkich nieobsłużonych awarii. Oto implementacja dla tego samego github.com/MindorksOpenSource/CrashReporter/blob/master/… .
Bali

Dobra daj mi to sprawdzić ...! Dzięki
Xenolion

2

Oto rozwiązanie, które może pomóc w zrzuceniu wszystkich dzienników do pliku tekstowego

adb logcat -d > logs.txt


0

Jeśli szukasz tylko dziennika awarii, gdy telefon jest podłączony do komputera, użyj widoku DDMS w Eclipse, a raport jest tam w LogCat w DDMS, gdy aplikacja ulega awarii podczas debugowania.


0

1) Podłącz telefon przez USB (z włączonymi opcjami debugowania programisty)

2) Otwórz terminal i przejdź do zestawu SDK systemu Android (dla komputerów Mac):

cd ~/Library/Android/sdk/platform-tools

3) Logcat z tego katalogu (w twoim terminalu), aby wygenerować stały przepływ logów (dla Mac):

./adb logcat

4) Otwórz aplikację, która ulega awarii, aby wygenerować dzienniki awarii

5) Ctrl + C, aby zatrzymać terminal i poszukać dzienników powiązanych z awarią aplikacji. Może brzmieć mniej więcej tak:

AndroidRuntime: FATAL EXCEPTION: main


0

Bazując na tym POST , użyj tej klasy jako zamiennika „TopExceptionHandler”

class TopExceptionHandler implements Thread.UncaughtExceptionHandler {
private Thread.UncaughtExceptionHandler defaultUEH;
private Activity app = null;
private String line;

public TopExceptionHandler(Activity app) {
    this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
    this.app = app;
}

public void uncaughtException(Thread t, Throwable e) {




    StackTraceElement[] arr = e.getStackTrace();
    String report = e.toString()+"\n\n";
    report += "--------- Stack trace ---------\n\n";
    for (int i=0; i<arr.length; i++) {
        report += "    "+arr[i].toString()+"\n";
    }
    report += "-------------------------------\n\n";

    // If the exception was thrown in a background thread inside
    // AsyncTask, then the actual exception can be found with getCause

    report += "--------- Cause ---------\n\n";
    Throwable cause = e.getCause();
    if(cause != null) {
        report += cause.toString() + "\n\n";
        arr = cause.getStackTrace();
        for (int i=0; i<arr.length; i++) {
            report += "    "+arr[i].toString()+"\n";
        }
    }
    report += "-------------------------------\n\n";

    try {
        FileOutputStream trace = app.openFileOutput("stack.trace",
                Context.MODE_PRIVATE);
        trace.write(report.getBytes());
        trace.close();



        Intent i = new Intent(Intent.ACTION_SEND);
        i.setType("message/rfc822");
        i.putExtra(Intent.EXTRA_EMAIL  , new String[]{"kevineyni@gmail.com"});
        i.putExtra(Intent.EXTRA_SUBJECT, "crash report azar");
        String body = "Mail this to kevineyni@gmail.com: " + "\n" + trace + "\n";
        i.putExtra(Intent.EXTRA_TEXT   , body);
        try {
            startActivity(Intent.createChooser(i, "Send mail..."));
        } catch (android.content.ActivityNotFoundException ex) {
           // Toast.makeText(MyActivity.this, "There are no email clients installed.", Toast.LENGTH_SHORT).show();
        }






      //  ReaderScopeActivity.this.startActivity(Intent.createChooser(sendIntent, "Title:"));

        //ReaderScopeActivity.this.deleteFile("stack.trace");

    } catch(IOException ioe) {
        // ...
    }

    defaultUEH.uncaughtException(t, e);
}

private void startActivity(Intent chooser) {
}

}

.....

w tym samym pliku klasy java (Activity) .....

Public class MainActivity.....

.....

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Thread.setDefaultUncaughtExceptionHandler(new TopExceptionHandler(this));

.....


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.