【发布时间】:2011-04-08 06:55:22
【问题描述】:
我有一个不在市场上的应用程序(使用调试证书签名),但我想在我的应用程序崩溃时获取崩溃日志数据。在哪里可以找到我的应用崩溃原因的日志?
【问题讨论】:
我有一个不在市场上的应用程序(使用调试证书签名),但我想在我的应用程序崩溃时获取崩溃日志数据。在哪里可以找到我的应用崩溃原因的日志?
【问题讨论】:
如果您的应用正在被其他人下载并在远程设备上崩溃,您可能需要查看 Android 错误报告库(在 this SO post 中引用)。如果它只是在您自己的本地设备上,您可以使用LogCat. 即使在发生崩溃时设备没有连接到主机,连接设备并发出adb logcat 命令将下载整个 logcat 历史记录(在至少在它被缓冲的范围内,通常是大量的日志数据,它不是无限的)。这些选项中的任何一个都回答了您的问题吗?如果不是,您可以尝试澄清一下您在寻找什么吗?
【讨论】:
adb logcat。或者,您可以使用 Eclipse 插件中包含的 SDK 工具
$SDK_DIR/platform-tools/。显示错误:.\adb.exe logcat -v time *:E
实现这一点的方法是实现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
【讨论】:
你可以从控制台试试这个:
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.
【讨论】:
这是来自http://www.herongyang.com/Android/Debug-adb-logcat-Command-Debugging.html
你可以使用adb:
adb logcat AndroidRuntime:E *:S
【讨论】:
如果您使用的是 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 行的数组越界异常。
【讨论】:
您可以使用 Apphance。这是一项跨平台服务(现在主要是 Android、iOS 以及其他平台),允许远程调试任何移动设备(Android、iOS 现在 - 其他正在开发中)。它不仅仅是一个崩溃日志,实际上它还有更多:日志记录、测试人员报告问题、崩溃日志。集成大约需要 5 分钟。目前您可以申请内测。
免责声明:我是 Apphance 背后的公司 Polidea 的 CTO,也是它的共同创造者。
更新:Apphance 不再是封闭测试版! 更新 2:Apphance 作为http://applause.com 产品的一部分提供
【讨论】:
libs 目录中,如this SO answer解释。 This github commit 显示了我需要对 WorldMap 应用程序进行更改才能使用 apphance。
这是崩溃日志的另一种解决方案。
Android 市场有名为“Crash Collector”的工具
查看以下链接了解更多信息
http://kpbird.blogspot.com/2011/08/android-application-crash-logs.html
【讨论】:
如果您正在寻找基本的崩溃报告工具,请尝试crashlytics。
如果您想要更高级的报告工具,请查看 Gryphonet。它会记录所有发生的崩溃以及导致崩溃的确切代码行以及自动标记,这些标记会向您显示用户在崩溃之前采取的步骤等等。
祝你好运!
【讨论】:
您可以通过this 使用 ACRA。将此库包含在您的项目中并对其进行配置,您可以(在您的电子邮件或 gdocs 中)收到他们的崩溃报告。对不起我的英语不好。
【讨论】:
为安卓应用使用 acra 崩溃报告器..Acra lib
【讨论】:
我创建了这个库来解决您的所有问题。 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)
【讨论】:
这是一个可以帮助您将所有日志转储到文本文件的解决方案
adb logcat -d > logs.txt
【讨论】:
你也可以使用库crashcatcher
【讨论】:
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
【讨论】:
如果您只是在手机连接到计算机时查找崩溃日志,请使用 Eclipse 中的 DDMS 视图,当您的应用在调试时崩溃时,该报告就在 DDMS 中的 LogCat 中。
【讨论】:
基于这个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));
.....
【讨论】:
从 android 试用 Carsh 日志应用。
使用link 下载应用程序。
【讨论】:
使用这个库`依赖{ ///........
实现'cat.ereza:customactivityoncrash:2.3.0'
}`
【讨论】:
` 括号表示路径和代码片段。要突出显示应用的名称或界面,请使用 粗体(** 括号)或 斜体(* 括号)字体。