Come ottenere i registri degli arresti anomali di Android?


155

Ho un'app che non si trova sul mercato (firmata con un certificato di debug), ma vorrei ottenere i dati del registro degli arresti anomali ogni volta che si blocca l'applicazione. Dove posso trovare un registro del motivo per cui la mia app si è bloccata?

Risposte:


139

Se la tua app viene scaricata da altre persone e si arresta in modo anomalo su dispositivi remoti, potresti voler esaminare una libreria di segnalazione errori Android (indicata in questo post SO ). Se si trova solo sul tuo dispositivo locale, puoi utilizzare LogCat. anche se il dispositivo non era connesso a un computer host quando si è verificato l'arresto anomalo, collegando il dispositivo ed eseguendo un adb logcatcomando scaricherà l'intera cronologia logcat (almeno nella misura in cui esso è bufferizzato che di solito è un carico di dati di registro, non è semplicemente infinito). Una di queste opzioni risponde alla tua domanda? Altrimenti puoi tentare di chiarire un po 'di più quello che stai cercando?


2
puoi dettagliare come usare il comando adb logcat? Lo eseguo nella directory / SDK / tools? Ci sono delle bandiere che dovrei notare? ecc.
jesses.co.tt il

2
@ jesses.co.tt Sì, basta eseguire adb logcatda qualunque directory adb si trovi. In alternativa puoi usare gli strumenti SDK inclusi nel plugin Eclipse
Chris Thompson,

2
Crashlytics è il miglior software di registrazione remota delle eccezioni che abbia mai usato. Esce in tutte le mie app, dai un'occhiata.
Jacksonkr,

adb.exe si trova in $SDK_DIR/platform-tools/. Per mostrare l'errore:.\adb.exe logcat -v time *:E
Harun

53

Il modo per farlo è implementare l' Thread.UncaughtExceptionHandlerinterfaccia e passarla Thread.setDefaultUncaughtExceptionHandler()all'inizio della tua attività onCreate(). Ecco la classe di implementazione 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);
    }
}

Nota Lasciamo che il framework Android di defaultUEH lo gestisca.

Nella parte superiore della tua attività registra un'istanza di classe precedente come questa:

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

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

Questo gestore salva la traccia in un file. Al ReaderScoperiavvio successivo, rileva il file e richiede all'utente se desidera inviarlo via e-mail allo sviluppatore.

Per inviare tramite e-mail la traccia dello stack, eseguire il codice seguente per comprimerlo in 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");

Oppure puoi anche usare ACRA Error Reporting System. Basta includere ACRA.jar nelle librerie del progetto e usare lo snippet di codice seguente prima della dichiarazione della classe di attività del lanciatore

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

oppure puoi provarlo dalla console: -

adb logcat -b crash 

Non sarà la riga defaultUEH.uncaughtException (t, e); chiamare il metodo uncaughtException () all'infinito?
Mickael Bergeron Néron,

@ MickaelBergeronNéron no: trasferirà lo stesso Throwable allo stesso gestore di livello superiore.
formato dal


36

Puoi provarlo dalla console:

adb logcat --buffer=crash 

Maggiori informazioni su questa opzione:

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

Se stai usando Eclipse, assicurati di usare il debug e di non eseguirlo. Assicurati di essere nella prospettiva di debug (in alto a destra) Potrebbe essere necessario premere "Riprendi" (F8) alcune volte per stampare il registro. Il registro degli arresti anomali sarà nella finestra Logcat in basso, fai doppio clic per lo schermo intero e assicurati di scorrere verso il basso. Vedrai il testo rosso per gli errori, la traccia dell'arresto anomalo sarà simile

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

Le parti importanti per questo sono

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)

quelli ci dicono che era una matrice fuori limite sulla riga 13 di main.java nel metodo onCrate.


9

Puoi usare Apphance. Questo è un servizio multipiattaforma (ora principalmente Android, iOS con altre piattaforme in arrivo) che consente di eseguire il debug in remoto di qualsiasi dispositivo mobile (Android, iOS ora - altri in fase di sviluppo). È molto più di un semplice crashlog, infatti è molto di più: registrazione, segnalazione di problemi da parte dei tester, crashlog. L'integrazione richiede circa 5 minuti. Attualmente puoi richiedere l'accesso alla beta chiusa.

Disclaimer: sono CTO di Polidea, una società dietro Apphance e co-creatore di essa.

Aggiornamento: Apphance non è più la beta chiusa! Aggiornamento 2: Apphance è disponibile come parte dell'offerta http://applause.com


2
Ho appena provato l'apprezzamento e mi piace. I documenti hanno perso un punto chiave durante l'integrazione della libreria apphance nella tua app; con l'ultima versione di Eclipse ADT, è necessario inserire apphance.jar nella libsdirectory come spiega questa risposta SO. Questo commit github mostra le modifiche che avevo bisogno di apportare alla mia app WorldMap per usare apphance.
JohnnyLambada,

@HohnnyLambada Grazie per il tuo commento. Abbiamo aggiornato la documentazione per renderlo più chiaro.
Piotr Duda,

12
questo non dovrebbe avere così tante frecce in alto che costa 10 volte di più rispetto alla maggior parte dei budget di sviluppo ($ 2.500 al mese!)
user26676,

l'apphance è 404 alla data di questo commento.
DaveP,

Corretta. È stato acquistato già molto tempo fa da uTest che ha poi rinominato tutta la sua offerta (inclusa la funzionalità di Aphhance) in Applausi. Così ora è applause.com
Jarek Potiuk


4

Puoi usare ACRA da questo . Includendo questa libreria ai tuoi progetti e configurandola, potresti ricevere (nella tua e-mail o gdocs) i loro rapporti sugli arresti anomali. Scusa per il mio cattivo inglese.


4

Se stai cercando uno strumento di base per la segnalazione degli arresti anomali , prova crashlytics .

Se desideri uno strumento di reporting più avanzato, Acquista Gryphonet . Registra tutti gli arresti anomali verificatisi insieme alla riga esatta di codice che ha causato l'incidente insieme a marcatori automatici che mostrano i passaggi che l'utente ha effettuato prima dell'incidente e altro ancora.

In bocca al lupo!



2

Ho creato questa libreria per risolvere tutti i tuoi problemi. Crash Reporter è uno strumento utile per catturare tutti i tuoi arresti anomali e registrarli nel dispositivo localmente

Basta aggiungere questa dipendenza e sei a posto.

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

Trova tutti i tuoi arresti anomali nel dispositivo localmente e correggili a tuo piacimento. Gli arresti anomali vengono salvati utilizzando il formato di data e ora facilmente tracciabile. Inoltre fornisce anche API per acquisire eccezioni registrate utilizzando il metodo seguente.

CrashRepoter.logException(Exception e)

Qual è la classe Java che hai usato per ottenere i Crash Logs di un dispositivo?
Xenolion

L'interfaccia Thread.UncaughtExceptionHandler viene utilizzata per acquisire tutti gli arresti anomali non gestiti. Ecco l'implementazione per lo stesso github.com/MindorksOpenSource/CrashReporter/blob/master/… .
Bali,

Va bene fammi controllare ...! Grazie
Xenolion l'

2

Ecco una soluzione che può aiutarti a scaricare tutti i log in un file di testo

adb logcat -d > logs.txt


0

Se stai solo cercando il registro degli arresti anomali mentre il telefono è collegato al computer, usa la vista DDMS in Eclipse e il rapporto è proprio lì in LogCat in DDMS quando l'app si arresta in modo anomalo durante il debug.


0

1) Collegare il telefono tramite USB (con opzioni di debug per sviluppatori abilitate)

2) Apri Terminale e vai al tuo SDK Android (per Mac):

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

3) Logcat da quella directory (nel tuo terminale) per generare un flusso costante di log (per Mac):

./adb logcat

4) Apri l'app che si arresta in modo anomalo per generare i registri degli arresti anomali

5) Ctrl + C per arrestare il terminale e cercare i registri associati all'app che si arresta in modo anomalo. Potrebbe dire qualcosa di simile al seguente:

AndroidRuntime: FATAL EXCEPTION: main


0

Basandosi su questo POST , utilizzare questa classe come sostituto di "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) {
}

}

.....

nello stesso file di classe Java (attività) .....

Public class MainActivity.....

.....

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

.....


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.