Comment obtenir les journaux de crash Android?


155

J'ai une application qui n'est pas sur le marché (signée avec un certificat de débogage), mais je souhaite obtenir les données du journal des incidents chaque fois que mon application plante. Où puis-je trouver un journal des raisons pour lesquelles mon application a planté?

Réponses:


139

Si votre application est téléchargée par d'autres personnes et se bloque sur des appareils distants, vous pouvez consulter une bibliothèque de rapports d'erreurs Android (référencée dans cet article SO ). Si c'est juste sur votre propre appareil local, vous pouvez utiliser LogCat. Même si l'appareil n'était pas connecté à une machine hôte lorsque la panne s'est produite, la connexion de l'appareil et l'exécution d'une adb logcatcommande téléchargeront l'intégralité de l'historique de Logcat (au moins dans la mesure où il est mis en mémoire tampon, ce qui est généralement un loooot de données de journal, ce n'est tout simplement pas infini). L'une de ces options répond-elle à votre question? Sinon, pouvez-vous essayer de clarifier ce que vous recherchez un peu plus?


2
pouvez-vous détailler comment utiliser la commande adb logcat? Dois-je l'exécuter dans le répertoire / SDK / tools? Y a-t-il des drapeaux à noter? etc.
jesses.co.tt

2
@ jesses.co.tt Oui, exécutez simplement à adb logcatpartir du répertoire dans lequel adb se trouve. Vous pouvez également utiliser les outils SDK inclus dans le plugin Eclipse
Chris Thompson

2
Crashlytics est le meilleur logiciel de journalisation des exceptions à distance que j'ai jamais utilisé. Il sort dans toutes mes applications, vérifiez-le.
Jacksonkr

adb.exe se trouve dans $SDK_DIR/platform-tools/. Pour afficher l'erreur:.\adb.exe logcat -v time *:E
Harun

53

La façon de faire est d'implémenter l' Thread.UncaughtExceptionHandlerinterface et de la transmettre Thread.setDefaultUncaughtExceptionHandler()au début de votre activité onCreate(). Voici la classe d'implémentation 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);
    }
}

Remarque Nous laissons le defaultUEH du framework Android le gérer.

En haut de votre activité, enregistrez une instance de la classe ci-dessus comme celle-ci:

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

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

Ce gestionnaire enregistre la trace dans un fichier. QuandReaderScope redémarrage suivant, il détecte le fichier et demande à l'utilisateur s'il souhaite l'envoyer par e-mail au développeur.

Pour envoyer le suivi de la pile par e-mail, exécutez le code suivant pour le regrouper dans un 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");

Ou vous pouvez également utiliser ACRA Error Reporting System.Incluez simplement le fichier ACRA.jar dans vos bibliothèques de projet et utilisez l'extrait de code ci-dessous avant la déclaration de la classe d'activité du lanceur.

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

ou vous pouvez essayer ceci depuis la console: -

adb logcat -b crash 

La ligne ne sera pas defaultUEH.uncaughtException (t, e); appeler la méthode uncaughtException () indéfiniment?
Mickael Bergeron Néron

@ MickaelBergeronNéron non - il transférera simplement le même Throwable au gestionnaire de niveau supérieur.
formatBCE


36

Vous pouvez essayer ceci depuis la console:

adb logcat --buffer=crash 

Plus d'informations sur cette 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

Si vous utilisez Eclipse, assurez-vous d'utiliser le débogage et de ne pas l'exécuter. Assurez-vous que vous êtes dans la perspective de débogage (en haut à droite). Vous devrez peut-être appuyer sur «Reprendre» (F8) plusieurs fois pour que le journal s'imprime. Le journal des pannes sera dans la fenêtre Logcat en bas - double-cliquez pour le plein écran et assurez-vous de faire défiler vers le bas. Vous verrez du texte rouge pour les erreurs, la trace de crash sera quelque chose comme

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

Les parties importantes pour celui-ci sont

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)

ceux-ci nous disent que c'était une exception de tableau hors limites sur la ligne 13 de main.java dans la méthode onCrate.


9

Vous pouvez utiliser Apphance. Il s'agit d'un service multiplateforme (maintenant principalement Android, iOS avec d'autres plates-formes en route) qui permet de déboguer à distance n'importe quel appareil mobile (Android, iOS maintenant - d'autres en cours de développement). C'est bien plus qu'un simple journal de crash, en fait c'est bien plus: journalisation, rapport de problèmes par les testeurs, crashlogs. L'intégration prend environ 5 minutes. Actuellement, vous pouvez demander l'accès à la version bêta fermée.

Disclaimer: Je suis CTO de Polidea, une entreprise derrière Apphance et co-créateur de celui-ci.

Mise à jour: Apphance n'est plus en version bêta fermée! Mise à jour 2: Apphance est disponible dans le cadre de l' offre http://applause.com


2
J'ai juste essayé apphance et j'aime ça. La documentation a manqué un point clé lors de l'intégration d'apphance lib dans votre application; avec la dernière version d'Eclipse ADT, vous devez mettre le fichier apphance.jar dans le libsrépertoire comme l' explique cette réponse SO. Ce commit github montre les modifications que je devais apporter à mon application WorldMap pour utiliser apphance.
JohnnyLambada

@HohnnyLambada Merci pour votre commentaire. Nous avons mis à jour la documentation pour rendre cela plus clair.
Piotr Duda

12
cela ne devrait pas avoir autant de flèches vers le haut que cela coûte 10 fois plus que la plupart des budgets de développement (2500 $ par mois!)
user26676

apphance est 404 à la date de ce commentaire.
DaveP

Correct. Il y a déjà longtemps, uTest a rebaptisé l'ensemble de son offre (y compris la fonctionnalité d'Aphhance) en Applause. Alors maintenant , il est applause.com
Jarek Potiuk


4

Vous pouvez utiliser ACRA à partir de cela . En incluant cette bibliothèque dans vos projets et en la configurant, vous pourriez recevoir (dans votre email ou gdocs) leurs rapports de plantage. Désolé pour mon mauvais anglais.


4

Si vous recherchez un outil de base de rapport de plantage, essayez crashlytics .

Si vous voulez un outil de reporting plus avancé, Checkout Gryphonet . Il enregistre tous les accidents survenus avec la ligne de code exacte qui a provoqué le crash ainsi que des marqueurs automatisés qui vous montrent les étapes que l'utilisateur a suivies avant le crash et plus encore.

Bonne chance!



2

J'ai créé cette bibliothèque pour résoudre tous vos problèmes. Crash Reporter est un outil pratique pour capturer tous vos plantages et les enregistrer localement dans l'appareil

Ajoutez simplement cette dépendance et vous êtes prêt à partir.

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

Trouvez tous vos plantages dans l'appareil localement et corrigez-les à votre convenance. Les plantages sont enregistrés en utilisant un format de date et d'heure facile à suivre. De plus, il fournit également une API pour capturer les exceptions enregistrées à l'aide de la méthode ci-dessous.

CrashRepoter.logException(Exception e)

Quelle est la classe Java que vous avez utilisée pour obtenir les journaux de panne d'un périphérique?
Xenolion

L'interface Thread.UncaughtExceptionHandler est utilisée pour capturer tous les plantages non gérés. Voici l'implémentation du même github.com/MindorksOpenSource/CrashReporter/blob/master/… .
Bali

Ok, laisse-moi vérifier ça ...! Merci
Xenolion

2

Voici une solution qui peut vous aider à vider tous les journaux dans un fichier texte

adb logcat -d > logs.txt


0

Si vous recherchez simplement le journal des pannes alors que votre téléphone est connecté à l'ordinateur, utilisez la vue DDMS dans Eclipse et le rapport se trouve juste là dans LogCat dans DDMS lorsque votre application se bloque pendant le débogage.


0

1) Branchez le téléphone via USB (avec les options de débogage du développeur activées)

2) Ouvrez Terminal et accédez à votre SDK Android (pour Mac):

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

3) Logcat à partir de ce répertoire (dans votre terminal) pour générer un flux constant de journaux (pour Mac):

./adb logcat

4) Ouvrez votre application qui plante pour générer des journaux de panne

5) Ctrl + C pour arrêter le terminal et rechercher les journaux associés à l'application qui plante. Cela peut dire quelque chose comme ce qui suit:

AndroidRuntime: FATAL EXCEPTION: main


0

Basé sur ce POST , utilisez cette classe en remplacement de "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) {
}

}

.....

dans le même fichier de classe java (Activity) .....

Public class MainActivity.....

.....

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

.....


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.