【问题标题】:How to get Android crash logs?如何获取 Android 崩溃日志?
【发布时间】:2011-04-08 06:55:22
【问题描述】:

我有一个不在市场上的应用程序(使用调试证书签名),但我想在我的应用程序崩溃时获取崩溃日志数据。在哪里可以找到我的应用崩溃原因的日志?

【问题讨论】:

    标签: android logging crash


    【解决方案1】:

    如果您的应用正在被其他人下载并在远程设备上崩溃,您可能需要查看 Android 错误报告库(在 this SO post 中引用)。如果它只是在您自己的本地设备上,您可以使用LogCat. 即使在发生崩溃时设备没有连接到主机,连接设备并发出adb logcat 命令将下载整个 logcat 历史记录(在至少在它被缓冲的范围内,通常是大量的日志数据,它不是无限的)。这些选项中的任何一个都回答了您的问题吗?如果不是,您可以尝试澄清一下您在寻找什么吗?

    【讨论】:

    • 您能详细说明如何使用 adb logcat 命令吗?我在 /SDK/tools 目录中运行它吗?有什么我应该注意的标志吗?等
    • @jesses.co.tt 是的,只需从 adb 所在的任何目录运行 adb logcat。或者,您可以使用 Eclipse 插件中包含的 SDK 工具
    • Crashlytics 是我用过的最好的远程异常记录软件。它在我所有的应用程序中都消失了,请检查一下。
    • adb.exe 位于$SDK_DIR/platform-tools/。显示错误:.\adb.exe logcat -v time *:E
    【解决方案2】:

    实现这一点的方法是实现Thread.UncaughtExceptionHandler 接口并将其传递给Activity 的onCreate() 开头的Thread.setDefaultUncaughtExceptionHandler()。这里是实现类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 框架的 defaultUEH 来处理它。

    在您的 Activity 顶部注册一个上述类的实例,如下所示:

    @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 并在启动器活动类声明之前使用以下代码 sn-p

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

    或者你可以从控制台试试这个:-

    adb logcat -b crash 
    

    【讨论】:

    • 不会行 defaultUEH.uncaughtException(t, e);无限调用 uncaughtException() 方法?
    • @MickaelBergeronNéron no - 它只会将相同的 Throwable 转移到顶级处理程序。
    • 对我来说是一个很棒的发现。已将数据记录到 Google 电子表格中。让我的调试工作更轻松。
    【解决方案3】:

    你可以从控制台试试这个:

    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.
    

    【讨论】:

      【解决方案4】:

      这是来自http://www.herongyang.com/Android/Debug-adb-logcat-Command-Debugging.html

      你可以使用adb:

      adb logcat AndroidRuntime:E *:S
      

      【讨论】:

      • 'adb logcat -d CRASH:E :S'
      【解决方案5】:

      如果您使用的是 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)
      

      这些告诉我们这是 onCrate 方法中 main.java 的第 13 行的数组越界异常。

      【讨论】:

        【解决方案6】:

        您可以使用 Apphance。这是一项跨平台服务(现在主要是 Android、iOS 以及其他平台),允许远程调试任何移动设备(Android、iOS 现在 - 其他正在开发中)。它不仅仅是一个崩溃日志,实际上它还有更多:日志记录、测试人员报告问题、崩溃日志。集成大约需要 5 分钟。目前您可以申请内测。

        免责声明:我是 Apphance 背后的公司 Polidea 的 CTO,也是它的共同创造者。

        更新:Apphance 不再是封闭测试版! 更新 2:Apphance 作为http://applause.com 产品的一部分提供

        【讨论】:

        • 我只是尝试了apphance并且喜欢它。在将 apphance lib 集成到您的应用程序时,文档遗漏了一个关键点;使用最新版本的 Eclipse ADT,您必须将 apphance.jar 放在libs 目录中,如this SO answer解释。 This github commit 显示了我需要对 WorldMap 应用程序进行更改才能使用 apphance。
        • @HohnnyLambada 感谢您的评论。我们更新了文档以使其更加清晰。
        • 这不应该得到这么多的向上箭头,它的成本是大多数开发预算的 10 倍(每月 2,500 美元!)
        • apphance 在此评论日期为 404。
        • 正确。 uTest 很久以前就已经提出了它,然后将他们的整个产品(包括 Aphhance 的功能)重新命名为 Applause。所以现在是applause.com
        【解决方案7】:

        这是崩溃日志的另一种解决方案。

        Android 市场有名为“Crash Collector”的工具

        查看以下链接了解更多信息

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

        【讨论】:

        • 不适用于 Android 4.1 及更高版本(读取日志的新权限)。
        【解决方案8】:

        如果您正在寻找基本的崩溃报告工具,请尝试crashlytics

        如果您想要更高级的报告工具,请查看 Gryphonet。它会记录所有发生的崩溃以及导致崩溃的确切代码行以及自动标记,这些标记会向您显示用户在崩溃之前采取的步骤等等。

        祝你好运!

        【讨论】:

        • Crashlytics 也不错,因为它可以跨平台用于 Android、iOS 等......
        【解决方案9】:

        您可以通过this 使用 ACRA。将此库包含在您的项目中并对其进行配置,您可以(在您的电子邮件或 gdocs 中)收到他们的崩溃报告。对不起我的英语不好。

        【讨论】:

          【解决方案10】:

          为安卓应用使用 acra 崩溃报告器..Acra lib

          【讨论】:

            【解决方案11】:

            我创建了这个库来解决您的所有问题。 Crash Reporter is a handy tool to capture all your crashes and log them in device locally

            只需添加此依赖项即可。

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

            在本地查找设备中的所有崩溃并在您方便时修复它们。 使用易于跟踪的日期和时间格式保存崩溃。此外,它还提供 API 用于使用以下方法捕获 Logged Exceptions。

            CrashRepoter.logException(Exception e)
            

            【讨论】:

            【解决方案12】:

            这是一个可以帮助您将所有日志转储到文本文件的解决方案

            adb logcat -d > logs.txt
            

            【讨论】:

              【解决方案13】:

              你也可以使用库crashcatcher

              【讨论】:

                【解决方案14】:

                1) 通过 USB 插入手机(启用开发人员调试选项)

                2) 打开终端并导航到您的 Android SDK(适用于 Mac):

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

                3) 来自该目录(在您的终端中)的 Logcat 以生成恒定的日志流(对于 Mac):

                ./adb logcat

                4) 打开崩溃的应用以生成崩溃日志

                5) Ctrl+C 停止终端并查找与崩溃的应用程序相关的日志。它可能会这样说:

                AndroidRuntime: FATAL EXCEPTION: main

                【讨论】:

                  【解决方案15】:

                  如果您只是在手机连接到计算机时查找崩溃日志,请使用 Eclipse 中的 DDMS 视图,当您的应用在调试时崩溃时,该报告就在 DDMS 中的 LogCat 中。

                  【讨论】:

                    【解决方案16】:

                    基于这个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类文件中(Activity) .....

                    Public class MainActivity.....
                    

                    .....

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

                    .....

                    【讨论】:

                      【解决方案17】:

                      从 android 试用 Carsh 日志应用。

                      使用link 下载应用程序。

                      【讨论】:

                        【解决方案18】:

                        使用这个库`依赖{ ///........

                        实现'cat.ereza:customactivityoncrash:2.3.0'

                        }`

                        【讨论】:

                        • 您的答案存在一些格式问题。尝试改进它。使用` 括号表示路径和代码片段。要突出显示应用的名称或界面,请使用 粗体** 括号)或 斜体* 括号)字体。
                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2016-05-20
                        • 2011-06-24
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多