如何从 Android 应用程序获取崩溃数据(至少是堆栈跟踪)?至少在使用电缆检索我自己的设备上工作时,但理想情况下,该应用程序可以在野外运行的任何应用程序实例中运行,以便我可以对其进行改进并使其更加牢固。
您可以尝试ACRA(适用于 Android 的应用程序崩溃报告)库:
ACRA 是一个使 Android 应用程序能够将其崩溃报告自动发布到 GoogleDoc 表单的库。它面向 Android 应用程序开发人员,以帮助他们在崩溃或行为错误时从其应用程序获取数据。
它易于安装在您的应用程序中,可高度配置,并且不需要您在任何地方托管服务器脚本... 报告将发送到 Google Doc 电子表格!
出于示例应用程序和调试目的,我使用一个简单的解决方案,该解决方案使我可以将 stacktrace 写入设备的 sd 卡和 / 或将其上传到服务器。该解决方案的灵感来自 Project android-remote-stacktrace (特别是保存到设备和上载到服务器的部件),我认为它解决了 Soonil 提到的问题。这不是最佳选择,但是它可以工作,如果您想在生产应用程序中使用它,则可以对其进行改进。如果决定将堆栈跟踪上载到服务器,则可以使用 php 脚本( index.php
)查看它们。如果您有兴趣,可以在下面找到所有源代码 - 一个 Java 类用于您的应用程序,两个可选 php 脚本,用于托管上传的 stacktrace 的服务器。
在上下文中(例如主活动),调用
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");
?>
您也可以尝试BugSense 。 BugSense 收集并分析了所有崩溃报告,并为您提供有意义的可视化报告。它是免费的,并且只有 1 行代码可以集成。
免责声明:我是联合创始人