我怎样才能从我的Android应用程序获取崩溃数据(至少是堆栈跟踪)?最好能够通过电缆从自己的设备检索,但更理想的是能够从任何正在运行的应用程序实例中检索,这样我就可以改善它并使其更加稳定。
我怎样才能从我的Android应用程序获取崩溃数据(至少是堆栈跟踪)?最好能够通过电缆从自己的设备检索,但更理想的是能够从任何正在运行的应用程序实例中检索,这样我就可以改善它并使其更加稳定。
您可以尝试使用ACRA (Android 应用程序崩溃报告)库:
ACRA 是一个库,使 Android 应用程序能够自动将其崩溃报告发布到 Google 表单中。它面向的是 Android 应用程序开发者,帮助他们在应用程序崩溃或行为异常时获取数据。
您可以轻松地在您的应用程序中安装 ACRA 库,它高度可配置,并不需要您在任何地方托管服务器脚本...... 报告会发送到 Google 文档电子表格中!
index.php
)来查看它们。如果您感兴趣,可以在下面找到所有源代码 - 一个Java类用于您的应用程序以及两个可选的php脚本用于托管上传的堆栈跟踪的服务器。if(!(Thread.getDefaultUncaughtExceptionHandler() instanceof CustomExceptionHandler)) {
Thread.setDefaultUncaughtExceptionHandler(new CustomExceptionHandler(
"/sdcard/<desired_local_path>", "http://<desired_url>/upload.php"));
}
CustomExceptionHandler
public class CustomExceptionHandler implements UncaughtExceptionHandler {
private UncaughtExceptionHandler defaultUEH;
private String localPath;
private String url;
/*
* if any of the parameters is null, the respective functionality
* will not be used
*/
public CustomExceptionHandler(String localPath, String url) {
this.localPath = localPath;
this.url = url;
this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
}
public void uncaughtException(Thread t, Throwable e) {
String timestamp = TimestampFormatter.getInstance().getTimestamp();
final Writer result = new StringWriter();
final PrintWriter printWriter = new PrintWriter(result);
e.printStackTrace(printWriter);
String stacktrace = result.toString();
printWriter.close();
String filename = timestamp + ".stacktrace";
if (localPath != null) {
writeToFile(stacktrace, filename);
}
if (url != null) {
sendToServer(stacktrace, filename);
}
defaultUEH.uncaughtException(t, e);
}
private void writeToFile(String stacktrace, String filename) {
try {
BufferedWriter bos = new BufferedWriter(new FileWriter(
localPath + "/" + filename));
bos.write(stacktrace);
bos.flush();
bos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private void sendToServer(String stacktrace, String filename) {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("filename", filename));
nvps.add(new BasicNameValuePair("stacktrace", stacktrace));
try {
httpPost.setEntity(
new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
httpClient.execute(httpPost);
} catch (IOException e) {
e.printStackTrace();
}
}
}
upload.php
<?php
$filename = isset($_POST['filename']) ? $_POST['filename'] : "";
$message = isset($_POST['stacktrace']) ? $_POST['stacktrace'] : "";
if (!ereg('^[-a-zA-Z0-9_. ]+$', $filename) || $message == ""){
die("This script is used to log debug data. Please send the "
. "logging message and a filename as POST variables.");
}
file_put_contents($filename, $message . "\n", FILE_APPEND);
?>
index.php
<?php
$myDirectory = opendir(".");
while($entryName = readdir($myDirectory)) {
$dirArray[] = $entryName;
}
closedir($myDirectory);
$indexCount = count($dirArray);
sort($dirArray);
print("<TABLE border=1 cellpadding=5 cellspacing=0 \n");
print("<TR><TH>Filename</TH><TH>Filetype</th><th>Filesize</TH></TR>\n");
for($index=0; $index < $indexCount; $index++) {
if ((substr("$dirArray[$index]", 0, 1) != ".")
&& (strrpos("$dirArray[$index]", ".stacktrace") != false)){
print("<TR><TD>");
print("<a href=\"$dirArray[$index]\">$dirArray[$index]</a>");
print("</TD><TD>");
print(filetype($dirArray[$index]));
print("</TD><TD>");
print(filesize($dirArray[$index]));
print("</TD></TR>\n");
}
}
print("</TABLE>\n");
?>
HttpPost httpPost = new HttpPost(url);
放在异步任务(或处理程序...单独的线程)中。 - Bryan Denny在 Android 2.2 版本中,现在可以自动从 Android 市场应用程序获取崩溃报告:
为 Android 市场应用程序提供了新的错误报告功能,使开发人员能够从用户处接收崩溃和冻结报告。当开发者登录其发布者帐户时,这些报告将可用。
http://developer.android.com/sdk/android-2.2-highlights.html
使用 Thread.setDefaultUncaughtExceptionHandler()
可以处理这些异常,但是这似乎会干扰 Android 处理异常的方法。我尝试使用了这样的一个 handler:
private class ExceptionHandler implements Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread thread, Throwable ex){
Log.e(Constants.TAG, "uncaught_exception_handler: uncaught exception in thread " + thread.getName(), ex);
//hack to rethrow unchecked exceptions
if(ex instanceof RuntimeException)
throw (RuntimeException)ex;
if(ex instanceof Error)
throw (Error)ex;
//this should really never happen
Log.e(Constants.TAG, "uncaught_exception handler: unable to rethrow checked exception");
}
}
然而,即使重新抛出异常,我仍然无法获得所需的行为,即在允许Android关闭发生异常的组件的同时记录异常,因此过了一段时间后我放弃尝试了。Constants.TAG
是 Android 框架的一部分吗?第一次看到它,似乎找不到它。 - Haroun Hajem我看到这个问题太老了,希望我的答案对其他遇到相同问题的人有所帮助...
试试Crashlytics吧。它将深入了解所有设备上应用程序的崩溃情况,并通过电子邮件向您发送通知。而且最好的部分是完全免费使用。
好的,我查看了rrainn和Soonil提供的示例,并找到了一种解决方案,它不会破坏错误处理。
我修改了CustomExceptionHandler,使其存储来自我们关联新异常处理程序的线程的原始UncaughtExceptionHandler。在新的“uncaughtException”方法结束时,我只是使用存储的UncaughtExceptionHandler调用旧函数。
在DefaultExceptionHandler类中,您需要像这样的内容:
public class DefaultExceptionHandler implements UncaughtExceptionHandler{
private UncaughtExceptionHandler mDefaultExceptionHandler;
//constructor
public DefaultExceptionHandler(UncaughtExceptionHandler pDefaultExceptionHandler)
{
mDefaultExceptionHandler= pDefaultExceptionHandler;
}
public void uncaughtException(Thread t, Throwable e) {
//do some action like writing to file or upload somewhere
//call original handler
mStandardEH.uncaughtException(t, e);
// cleanup, don't know if really required
t.getThreadGroup().destroy();
}
}
通过对代码进行修改,您可以在http://code.google.com/p/android-remote-stacktrace上获得一个良好的工作基础,用于将日志记录到您的Web服务器或SD卡中。
谷歌开发者控制台实际上为您提供了那些崩溃并发送报告的应用程序的堆栈跟踪,它还有非常好的图表来帮助您查看信息,如下所示:
我一直在使用Crittercism来监控我的Android和iOS应用程序,是在TechCrunch上听说过的。目前为止感觉还不错!