Як отримати журнали аварійних збоїв на Android?


155

У мене є додаток, який не знаходиться на ринку (підписаний сертифікатом налагодження), але я хотів би отримати дані журналу аварій, коли мій додаток виходить з ладу. Де я можу знайти журнал, чому мій додаток вийшов з ладу?

Відповіді:


139

Якщо ваш додаток завантажується іншими людьми і виходить з ладу на віддалених пристроях, ви можете заглянути в бібліотеку звітів про помилки Android (на яку посилається в цій публікації SO ). Якщо це лише на вашому власному локальному пристрої, ви можете використовувати LogCat. Навіть якщо при виході збою пристрій не був підключений до хост-машини, підключення пристрою та видача adb logcatкоманди завантажують всю історію лог-котів (принаймні настільки, наскільки це є буферизованим, що зазвичай є циклом даних журналів, це просто не безмежно). Чи відповідає один із цих варіантів на ваше запитання? Якщо ви не можете спробувати уточнити, що ви шукаєте трохи більше?


2
Ви можете детально описати, як використовувати команду adb logcat? Чи запускаю це все в каталозі / SDK / інструменти? Чи є якісь прапори, які я повинен зазначити? пр.
jesses.co.tt

2
@ jesses.co.tt Так, просто запустіть adb logcatз будь-якої адреси каталогу, в якій знаходиться adb. Крім того, ви можете використовувати інструменти SDK, що входять до плагіна Eclipse
Кріс Томпсон,

2
Crashlytics - найкраще програмне забезпечення для віддаленого реєстрації винятків, яке я коли-небудь використовував. Він виходить у всіх моїх програмах, перевірте це.
Jacksonkr

adb.exe знаходиться в $SDK_DIR/platform-tools/. Показати помилку:.\adb.exe logcat -v time *:E
Харун

53

Спосіб це зробити - це реалізувати Thread.UncaughtExceptionHandlerінтерфейс і передати його Thread.setDefaultUncaughtExceptionHandler()на початку діяльності onCreate(). Ось клас реалізації 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);
    }
}

Примітка. Ми дозволяємо Android-програмі за замовчуваннямUEHH для її вирішення.

У верхній частині вашої діяльності зареєструйте такий примірник вище класу:

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

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

Цей обробник зберігає слід у файлі. При ReaderScopeнаступному перезавантаженні він виявляє файл і запитує користувача, якщо він хоче надіслати його електронною поштою розробнику.

Щоб надіслати електронну пошту сліду стека, виконайте наступний код, щоб запакувати його в електронному листі.

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

Або ви також можете скористатися системою звітування про помилки ACRA. Просто включіть ACRA.jar у вкладки проекту та скористайтесь наведеним нижче фрагментом коду перед оголошенням класу активності запуску.

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

або Ви можете спробувати це з консолі: -

adb logcat -b crash 

Не буде рядок за замовчуваннямUEH.uncaughtException (t, e); безмежно називати метод uncaughtException ()?
Мікаель Бергерон Нерон

@ MickaelBergeronNéron ні - він просто перенесе той же Throwable на верхній обробник.
форматBCE


36

Ви можете спробувати це з консолі:

adb logcat --buffer=crash 

Детальніше про цей варіант:

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

Якщо ви використовуєте Eclipse, переконайтеся, що ви використовуєте налагодження, а не запускаєте. Переконайтеся, що ви перебуваєте в перспективі налагодження (угорі праворуч) Можливо, вам доведеться кілька разів натиснути «Відновити» (F8), щоб журнал надрукував. Журнал аварійного завершення буде знаходитись у вікні Logcat внизу - двічі клацніть на повноекранному екрані та переконайтесь, що ви прокручуєте донизу. Ви побачите червоний текст для помилок, слід збою буде чимось на зразок

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

Важливими частинами цього є

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)

ті кажуть нам, що це був масив поза межами меж на лінії 13 main.java у методі onCrate.


9

Можна використовувати Apphance. Це крос-платформна послуга (в даний час в основному Android, iOS з іншими платформами на шляху), яка дозволяє віддалено налагоджувати будь-який мобільний пристрій (Android, iOS зараз - інші в розробці). Це набагато більше, ніж просто крах, насправді це набагато більше: ведення журналів, повідомлення про проблеми тестерами, збої. На інтеграцію потрібно близько 5 хвилин. На даний момент ви можете подати запит на доступ до закритої бета-версії.

Відмова: Я є представником компанії Polidea, компанією, що стоїть за Apphance, і є її співавтором.

Оновлення: Apphance більше не закритий бета-версією! Оновлення 2: Apphance доступний як частина http://applause.com розміщення


2
Я просто спробував apphance і мені подобається. Документи пропустили ключовий момент при інтеграції lib apphance у ваш додаток; з останньою версією Eclipse ADT, ви повинні помістити apphance.jar у libsкаталог, як пояснюється ця відповідь ТАК. Ця фіксація github показує зміни, які мені потрібно було внести в додаток WorldMap, щоб використовувати додаток.
JohnnyLambada

@HohnnyLambada Дякуємо за ваш коментар Ми оновили документацію, щоб зробити це зрозумілішим.
Петро Дуда

12
це не повинно отримати стільки стрілок вгору, це коштує в 10 разів більше, ніж більшість бюджетів розвитку (2500 доларів на місяць!)
користувач26676

На момент коментаря цей коментар становить 404.
DaveP

Правильно. Це було давно вже давно компанією uTest, яка потім відреагувала на цілу пропозицію (включаючи функцію Aphhance) на Аплодисменти. Так що тепер це applause.com
Ярек Potiuk

8

Ось ще одне рішення для Crash Log.

Android market має інструмент під назвою "Crash Collector"

Перевірте наступне посилання для отримання додаткової інформації

http://kpbird.blogspot.com/2011/08/android-application-crash-logs.html


3
Не працює на Android 4.1 і новіших версіях (нові дозволи на читання журналів).
кіт

4

Ви можете використовувати ACRA з цього . Включивши цю бібліотеку до своїх проектів і налаштувавши її, ви можете отримати (на свою електронну пошту чи gdocs) їхні звіти про збої. Вибачте за мою погану англійську.


4

Якщо ви шукаєте базовий інструмент звітності про аварійні ситуації, спробуйте крашлитики .

Якщо ви хочете більш досконалий інструмент звітування, Checkout Gryphonet . Він реєструє всі збої, що відбулися разом із точним рядком коду, який спричинив збій, а також автоматизованими маркерами, які показують вам кроки, які користувач робив до аварії та багато іншого.

Удачі!



2

Я створив цю бібліотеку, щоб вирішити всі ваші проблеми. Crash Reporter - це зручний інструмент для зйомки всіх ваших збоїв та реєстрації їх на локальному пристрої

Просто додайте цю залежність і вам добре піти.

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

Знайдіть усі ваші збої на пристрої локально та виправте їх за вашою зручністю. Збої зберігаються за допомогою формату дати та часу, який легко відстежувати. Крім того, він також надає API для захоплення зареєстрованих винятків за допомогою методу нижче.

CrashRepoter.logException(Exception e)

Що таке клас Java, який ви використовували для отримання журналів збоїв пристрою?
Ксеноліон

Інтерфейс Thread.UncaughtExceptionHandler використовується для зйомки всіх не оброблених збоїв. Ось реалізація для того ж github.com/MindorksOpenSource/CrashReporter/blob/master/… .
Балі

Гаразд, перевіри це ... Спасибі
Ксеноліон

2

Ось рішення, яке допоможе вам скинути всі журнали на текстовий файл

adb logcat -d > logs.txt


0

Якщо ви просто шукаєте журнал аварій, коли ваш телефон підключений до комп'ютера, скористайтеся поданням DDMS у Eclipse, і звіт знаходиться прямо в LogCat в межах DDMS, коли ваш додаток виходить з ладу під час налагодження.


0

1) Підключіть телефон через USB (увімкнено параметри налагодження розробника)

2) Відкрийте термінал і перейдіть до свого SDK для Android (для Mac):

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

3) Логката з цього каталогу (у своєму терміналі) для створення постійного потоку журналів (для Mac):

./adb logcat

4) Відкрийте додаток, яке виходить з ладу для створення журналів аварій

5) Ctrl + C, щоб зупинити термінал і шукати журнали, пов’язані з програмою, яка виходить з ладу. Це може говорити приблизно так:

AndroidRuntime: FATAL EXCEPTION: main


0

Базуючись на цьому POST , використовуйте цей клас як заміну "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) {
}

}

.....

у тому ж файлі класу Java (Діяльність) .....

Public class MainActivity.....

.....

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

.....


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.