如何从我的Android应用程序中获得崩溃数据(至少堆栈跟踪)?至少在我自己的设备上工作时可以通过电缆检索,但理想的情况是,从我的应用程序在野外运行的任何实例中都可以,这样我就可以改进它,使它更可靠。
当前回答
好吧,我看了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卡。
其他回答
谷歌改变了你实际得到的崩溃报告的数量。以前你只能得到手动报告的错误报告。
自从上次开发者大会和Android Vitals的引入,你也会从用户那里得到崩溃报告,这些用户已经启用了共享诊断数据。
您将看到从用户选择自动共享使用情况和诊断数据的Android设备收集的所有崩溃。可获得前两个月的数据。
查看崩溃和应用程序未响应(ANR)错误
If your app is being downloaded by other people and crashing on remote devices, you may want to look into an Android error reporting library (referenced in this SO post). If it's just on your own local device, you can use LogCat. Even if the device wasn't connected to a host machine when the crash occurred, connected the device and issuing an adb logcat command will download the entire logcat history (at least to the extent that it is buffered which is usually a loooot of log data, it's just not infinite). Do either of those options answer your question? If not can you attempt to clarify what you're looking for a bit more?
如果你想立即得到答案,你可以使用logcat
$adb shell logcat -f /sdcard/logoutput.txt *:E
如果您的日志中现在有太多垃圾,请先尝试清除它们。
$adb shell logcat -c
然后尝试运行您的应用程序,然后再次logcat。
谷歌Firebase是谷歌最新的(2016)方式,为您提供崩溃/错误数据在您的手机。 将它包含在您的构建中。Gradle文件:
compile 'com.google.firebase:firebase-crash:9.0.0'
致命崩溃会自动记录,不需要用户输入,你也可以记录非致命崩溃或其他事件,如下所示:
try
{
}
catch(Exception ex)
{
FirebaseCrash.report(new Exception(ex.toString()));
}
感谢资源在Stackoverflow中帮助我找到这个答案。
你可以直接在电子邮件中找到远程Android崩溃报告。记住你必须把你的电子邮件放在CustomExceptionHandler类中。
public static String sendErrorLogsTo = "tushar.pandey@virtualxcellence.com" ;
步骤:
1)在onCreate你的活动使用这段代码。
if(!(Thread.getDefaultUncaughtExceptionHandler() instanceof CustomExceptionHandler)) {
Thread.setDefaultUncaughtExceptionHandler(new CustomExceptionHandler(this));
}
第二)使用(rrainn)的CustomExceptionHandler类的重写版本,根据我的phpscript。
package com.vxmobilecomm.activity;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.AsyncTask;
import android.util.Log;
public class CustomExceptionHandler implements UncaughtExceptionHandler {
private UncaughtExceptionHandler defaultUEH;
public static String sendErrorLogsTo = "tushar.pandey@virtualxcellence.com" ;
Activity activity;
public CustomExceptionHandler(Activity activity) {
this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
this.activity = activity;
}
public void uncaughtException(Thread t, Throwable e) {
final Writer result = new StringWriter();
final PrintWriter printWriter = new PrintWriter(result);
e.printStackTrace(printWriter);
String stacktrace = result.toString();
printWriter.close();
String filename = "error" + System.nanoTime() + ".stacktrace";
Log.e("Hi", "url != null");
sendToServer(stacktrace, filename);
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";
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";
defaultUEH.uncaughtException(t, e);
}
private void sendToServer(String stacktrace, String filename) {
AsyncTaskClass async = new AsyncTaskClass(stacktrace, filename,
getAppLable(activity));
async.execute("");
}
public String getAppLable(Context pContext) {
PackageManager lPackageManager = pContext.getPackageManager();
ApplicationInfo lApplicationInfo = null;
try {
lApplicationInfo = lPackageManager.getApplicationInfo(
pContext.getApplicationInfo().packageName, 0);
} catch (final NameNotFoundException e) {
}
return (String) (lApplicationInfo != null ? lPackageManager
.getApplicationLabel(lApplicationInfo) : "Unknown");
}
public class AsyncTaskClass extends AsyncTask<String, String, InputStream> {
InputStream is = null;
String stacktrace;
final String filename;
String applicationName;
AsyncTaskClass(final String stacktrace, final String filename,
String applicationName) {
this.applicationName = applicationName;
this.stacktrace = stacktrace;
this.filename = filename;
}
@Override
protected InputStream doInBackground(String... params)
{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(
"http://suo-yang.com/books/sendErrorLog/sendErrorLogs.php?");
Log.i("Error", stacktrace);
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(
6);
nameValuePairs.add(new BasicNameValuePair("data", stacktrace));
nameValuePairs.add(new BasicNameValuePair("to",sendErrorLogsTo));
nameValuePairs.add(new BasicNameValuePair("subject",applicationName));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity1 = response.getEntity();
BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(
entity1);
is = bufHttpEntity.getContent();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return is;
}
@Override
protected void onPostExecute(InputStream result) {
super.onPostExecute(result);
Log.e("Stream Data", getStringFromInputStream(is));
}
}
// convert InputStream to String
private static String getStringFromInputStream(InputStream is) {
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
String line;
try {
br = new BufferedReader(new InputStreamReader(is));
while ((line = br.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}
}
推荐文章
- BottomSheetDialogFragment的圆角
- 在应用程序启动时出现“无法获得BatchedBridge,请确保您的bundle被正确打包”的错误
- 我如何改变默认对话框按钮的文本颜色在安卓5
- 更改单选按钮的圆圈颜色
- 如何在android中复制一个文件?
- adb找不到我的设备/手机(MacOS X)
- 如何在新的材质主题中改变背面箭头的颜色?
- androidviewpager与底部点
- 相同的导航抽屉在不同的活动
- 如何从视图中获得托管活动?
- 单一的TextView与多种颜色的文本
- 如何在非活动类(LocationManager)中使用getSystemService ?
- 在清单中注册应用程序类?
- Android:从数组中编程创建旋转器
- 如何在Visual Studio中找到堆栈跟踪?