如何获取Android崩溃日志?

184

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

17个回答

154

如果您的应用程序被其他人下载并在远程设备上崩溃,您可能需要查看一个Android错误报告库(在此SO帖子中引用)。 如果仅发生在本地设备上,则可以使用LogCat。 即使设备在崩溃发生时未连接到主机计算机,连接设备并发出adb logcat命令也会下载整个logcat历史记录(至少缓冲区大小范围内,通常是大量日志数据,但不是无限的)。 这两个选项是否回答了您的问题? 如果没有,您可以尝试澄清一下您正在寻找什么。


4
请问您需要详细介绍如何使用 adb logcat 命令吗?我需要澄清一下,这个命令是在 /SDK/tools 目录下执行吗?还有,有哪些标志需要注意吗? - jesses.co.tt
2
@jesses.co.tt 嗯,只需从adb所在的任何目录运行adb logcat即可。或者您可以使用包含在Eclipse插件中的SDK工具。 - Chris Thompson
3
Crashlytics 是我用过的最好的远程异常日志记录软件。它适用于我所有的应用程序,你可以试试看。 - Jacksonkr
1
adb.exe 位于 $SDK_DIR/platform-tools/。显示错误的命令为: .\adb.exe logcat -v time *:E - Harun

96

您可以尝试从控制台执行以下操作:

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.

1
非常感谢,它实时显示了崩溃日志!真的很有帮助。 - Hitesh Kumar Saini
这可能与特定的shell有关,但在zsh中,您需要用引号指示缓冲区类型。 - undefined

70
实现该功能的方式是实现Thread.UncaughtExceptionHandler接口,并将其传递给Thread.setDefaultUncaughtExceptionHandler(),在您的Activity的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框架的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错误报告系统。只需在项目libs中包含ACRA.jar,并在启动器活动类声明之前使用以下代码片段:

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

您可以尝试从控制台运行以下命令:

或者您可以尝试从控制台执行以下操作:

adb logcat -b crash 

默认行 defaultUEH.uncaughtException(t, e) 不会无限制地调用 uncaughtException() 方法吗? - Mickael Bergeron Néron
@MickaelBergeronNéron 不会 - 它只会将相同的 Throwable 传递到顶层处理程序。 - formatBCE
1
对我来说是个绝妙的发现。已经实现了数据记录到Google电子表格中。让我的调试工作变得更加轻松。 - Sriram Nadiminti

48

1
adb logcat -d CRASH:E :S - Kanwar Malik

9

如果您正在使用Eclipse,请确保使用调试而不是运行。 确保您处于调试视角(右上方) 您可能需要按下“Resume”(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)

这些告诉我们,是在onCreate方法中main.java的第13行发生了数组越界异常。


8
你可以使用Apphance。这是一个跨平台服务(目前主要支持Android和iOS,其他平台正在开发中),允许远程调试任何移动设备(现在支持Android和iOS,其他正在开发中)。它不仅仅是崩溃日志,实际上它更多:记录、测试人员报告问题、崩溃日志等。集成只需约5分钟。目前您可以申请访问封闭的beta版。
免责声明:我是Polidea公司的CTO,也是Apphance的共同创造者。
更新:Apphance不再是封闭的beta版! 更新2:Apphance作为http://applause.com提供的一部分可用。

2
我刚试用了Apphance并且很喜欢它。但是在将Apphance库集成到您的应用程序时,文档中遗漏了一个关键点;根据最新版本的Eclipse ADT,您必须将apphance.jar放置在“libs”目录中,就像这个 SO答案所解释的那样。这个github提交记录展示了我需要对我的WorldMap应用程序进行的更改以使用Apphance。 - JohnnyLambada
@HohnnyLambada 感谢您的评论。我们已经更新了文档以使其更加清晰明了。 - Piotr Duda
15
这个不应该收到那么多赞,因为它的费用比大多数开发预算高出10倍(每月$2,500!)。 - user26676
在本条评论发布时,Apphance处于404状态。 - DaveP
没错。Aphhance早已被uTest收购,后者重新品牌整个产品(包括Aphhance的功能),并更名为Applause。现在它的网址是http://applause.com/。 - Jarek Potiuk

8

4
不支持Android 4.1及以上版本(需要新权限来读取日志)。 - cat

5
如果您正在寻找一款基本的崩溃报告工具,请尝试crashlytics
如果您想要更高级的报告工具,请查看Gryphonet。它记录了所有发生的崩溃,包括导致崩溃的精确代码行以及自动标记,显示用户在崩溃之前所采取的步骤等等。
祝好运!

Crashlytics也很好,因为它是适用于Android、iOS等多个平台的。 - Carl Smith

5

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

adb logcat -d > logs.txt

4
您可以使用来自这里的 ACRA。将该库包含到您的项目中并进行配置,您就可以收到他们的崩溃报告(发送到您的电子邮件或gdocs中)。抱歉我的英语不好。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接