Wie bekomme ich Android-Absturzprotokolle?


155

Ich habe eine App, die nicht auf dem Markt ist (mit einem Debug-Zertifikat signiert), möchte aber bei jedem Absturz meiner Anwendung Absturzprotokolldaten abrufen. Wo finde ich ein Protokoll darüber, warum meine App abgestürzt ist?

Antworten:


139

Wenn Ihre App von anderen Personen heruntergeladen wird und auf Remote-Geräten abstürzt, sollten Sie sich eine Android-Fehlerberichtsbibliothek ansehen (auf die in diesem SO-Beitrag verwiesen wird ). Wenn es sich nur auf Ihrem eigenen lokalen Gerät befindet, können Sie Folgendes verwenden: LogCat. Auch wenn das Gerät zum Zeitpunkt des Absturzes nicht mit einem Host-Computer verbunden war, wird durch Anschließen des Geräts und Ausgeben eines adb logcatBefehls der gesamte Logcat-Verlauf heruntergeladen (zumindest in dem Maße, in dem dies der Fall ist) ist gepuffert, was normalerweise eine Menge Protokolldaten ist, es ist einfach nicht unendlich). Beantworten eine dieser Optionen Ihre Frage? Wenn nicht, können Sie versuchen zu klären, wonach Sie ein bisschen mehr suchen?


2
Können Sie detailliert beschreiben, wie der Befehl adb logcat verwendet wird? Führe ich dies im Verzeichnis / SDK / tools aus? Gibt es Flaggen, die ich beachten sollte? usw.
jesses.co.tt

2
@ jesses.co.tt Ja, führen Sie einfach das adb logcatVerzeichnis aus, in dem sich adb befindet. Alternativ können Sie die SDK-Tools verwenden, die im Eclipse-Plugin enthalten sind
Chris Thompson

2
Crashlytics ist die beste Remote-Ausnahmeprotokollierungssoftware, die ich je verwendet habe. Es geht in allen meinen Apps aus, schau es dir an.
Jacksonkr

adb.exe befindet sich in $SDK_DIR/platform-tools/. Um Fehler anzuzeigen:.\adb.exe logcat -v time *:E
Harun

53

Der Weg, dies zu tun, besteht darin, die Thread.UncaughtExceptionHandlerSchnittstelle zu implementieren und sie zu Thread.setDefaultUncaughtExceptionHandler()Beginn Ihrer Aktivität zu übergeben onCreate(). Hier ist die Implementierungsklasse 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);
    }
}

Hinweis Wir lassen das defaultUEH des Android-Frameworks damit umgehen.

Registrieren Sie oben in Ihrer Aktivität eine Instanz der oben genannten Klasse wie folgt:

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

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

Dieser Handler speichert die Ablaufverfolgung in einer Datei. Beim ReaderScopenächsten Neustart wird die Datei erkannt und der Benutzer aufgefordert, sie per E-Mail an den Entwickler zu senden.

Führen Sie den folgenden Code aus, um die Stapelverfolgung per E-Mail in eine E-Mail zu packen.

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");

Sie können auch das ACRA-Fehlerberichtssystem verwenden. Fügen Sie einfach die Datei ACRA.jar in Ihre Projektbibliotheken ein und verwenden Sie das folgende Codeausschnitt, bevor Sie die Aktivierungsklasse für den Launcher deklarieren

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

oder Sie können dies von der Konsole aus versuchen: -

adb logcat -b crash 

Wird nicht die Zeile defaultUEH.uncaughtException (t, e); die Methode uncaughtException () unendlich aufrufen?
Mickael Bergeron Néron

@ MickaelBergeronNéron nein - es wird nur das gleiche Throwable an den Top-Level-Handler übertragen.
FormatBCE


36

Sie können dies über die Konsole versuchen:

adb logcat --buffer=crash 

Weitere Informationen zu dieser Option:

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

Wenn Sie Eclipse verwenden, stellen Sie sicher, dass Sie Debug verwenden und nicht ausführen. Stellen Sie sicher, dass Sie sich in der Debug-Perspektive befinden (oben rechts). Möglicherweise müssen Sie einige Male auf "Fortsetzen" (F8) klicken, damit das Protokoll gedruckt wird. Das Absturzprotokoll befindet sich im Logcat-Fenster unten. Doppelklicken Sie auf Vollbild und stellen Sie sicher, dass Sie nach unten scrollen. Sie sehen roten Text für Fehler, die Absturzverfolgung ist so etwas wie

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

Die wichtigen Teile für diesen sind

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)

Diese sagen uns, dass es sich um eine Ausnahme außerhalb der Grenzen in Zeile 13 von main.java in der onCrate-Methode handelte.


9

Sie können Apphance verwenden. Dies ist ein plattformübergreifender Dienst (jetzt hauptsächlich Android, iOS mit anderen Plattformen auf dem Weg), mit dem jedes mobile Gerät (Android, iOS jetzt - andere in der Entwicklung) remote debuggen können. Es ist viel mehr als nur ein Crashlog, tatsächlich ist es viel mehr: Protokollierung, Meldung von Problemen durch Tester, Crashlogs. Die Integration dauert ca. 5 Minuten. Derzeit können Sie den Zugriff auf die Closed Beta beantragen.

Haftungsausschluss: Ich bin CTO von Polidea, einem Unternehmen hinter Apphance und Mitentwickler von Polidea.

Update: Apphance ist keine geschlossene Beta mehr! Update 2: Apphance ist als Teil des Angebots von http://applause.com verfügbar


2
Ich habe es gerade versucht und mag es. Die Dokumente haben einen wichtigen Punkt bei der Integration von apphance lib in Ihre App übersehen. Bei der neuesten Version von Eclipse ADT müssen Sie die Datei apphance.jar in das libsVerzeichnis stellen, wie in dieser SO-Antwort erläutert. Dieses Github-Commit zeigt die Änderungen an, die ich an meiner WorldMap-App vornehmen musste, um Apphance verwenden zu können.
Johnny Lambada

@HohnnyLambada Danke für deinen Kommentar. Wir haben die Dokumentation aktualisiert, um dies klarer zu machen.
Piotr Duda

12
Dies sollte nicht so viele Pfeile nach oben bringen, dass es 10x mehr kostet als die meisten Entwicklungsbudgets (2.500 USD pro Monat!)
user26676

Apphance ist 404 zum Datum dieses Kommentars.
DaveP

Richtig. Es wurde bereits vor langer Zeit von uTest gekauft, das dann sein gesamtes Angebot (einschließlich Aphhances Feature) in Applause umbenannte. So jetzt ist es applause.com
Jarek Potiuk


4

Sie können ACRA hieraus verwenden . Wenn Sie diese Bibliothek in Ihre Projekte aufnehmen und konfigurieren, können Sie (in Ihre E-Mail oder in Ihre GDCs) deren Absturzberichte erhalten. Entschuldigung für mein schlechtes Englisch.


4

Wenn Sie nach einem grundlegenden Tool zur Absturzberichterstattung suchen, versuchen Sie es mit Crashlytics .

Wenn Sie ein erweitertes Berichterstellungstool wünschen, klicken Sie auf Checkout Gryphonet . Es protokolliert alle aufgetretenen Abstürze zusammen mit der genauen Codezeile, die den Absturz verursacht hat, sowie automatisierten Markierungen, die Ihnen die Schritte anzeigen, die der Benutzer vor dem Absturz unternommen hat, und vieles mehr.

Viel Glück!



2

Ich habe diese Bibliothek erstellt, um alle Ihre Probleme zu lösen. Crash Reporter ist ein praktisches Tool, mit dem Sie alle Abstürze erfassen und lokal am Gerät anmelden können

Fügen Sie einfach diese Abhängigkeit hinzu und los geht's.

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

Finden Sie alle Ihre Abstürze im Gerät lokal und beheben Sie sie nach Belieben. Abstürze werden im leicht zu verfolgenden Datums- und Uhrzeitformat gespeichert. Außerdem bietet es eine API zum Erfassen protokollierter Ausnahmen mit der folgenden Methode.

CrashRepoter.logException(Exception e)

Mit welcher Java-Klasse haben Sie die Absturzprotokolle eines Geräts abgerufen?
Xenolion

Die Thread.UncaughtExceptionHandler-Schnittstelle wird verwendet, um alle nicht behandelten Abstürze zu erfassen. Hier ist die Implementierung für denselben github.com/MindorksOpenSource/CrashReporter/blob/master/… .
Bali

Okay, lass mich das überprüfen ...! Vielen Dank
Xenolion

2

Hier ist eine Lösung, mit der Sie alle Protokolle in einer Textdatei speichern können

adb logcat -d > logs.txt


0

Wenn Sie nur nach dem Absturzprotokoll suchen, während Ihr Telefon mit dem Computer verbunden ist, verwenden Sie die DDMS-Ansicht in Eclipse. Der Bericht befindet sich direkt in LogCat in DDMS, wenn Ihre App beim Debuggen abstürzt.


0

1) Schließen Sie das Telefon über USB an (mit aktivierten Developer Debugging-Optionen).

2) Öffnen Sie das Terminal und navigieren Sie zu Ihrem Android SDK (für Mac):

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

3) Logcat aus diesem Verzeichnis (in Ihrem Terminal), um einen konstanten Protokollfluss (für Mac) zu generieren:

./adb logcat

4) Öffnen Sie Ihre abstürzende App, um Absturzprotokolle zu erstellen

5) Strg + C, um das Terminal anzuhalten und nach den Protokollen zu suchen, die der abstürzenden App zugeordnet sind. Es kann ungefähr so ​​etwas sagen:

AndroidRuntime: FATAL EXCEPTION: main


0

Verwenden Sie diese Klasse basierend auf diesem POST als Ersatz für "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) {
}

}}

..... .....

in derselben Java-Klassendatei (Aktivität) .....

Public class MainActivity.....

..... .....

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

..... .....


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.