如何从我的Android应用程序中获得崩溃数据(至少堆栈跟踪)?至少在我自己的设备上工作时可以通过电缆检索,但理想的情况是,从我的应用程序在野外运行的任何实例中都可以,这样我就可以改进它,使它更可靠。
当前回答
我一直在Android和iOS应用中使用cratercism——我在techcrunch上听说过它们。到目前为止,他们都很满意!
其他回答
谷歌Play开发者控制台实际上为你提供了那些已经崩溃和发送报告的应用程序的堆栈跟踪,它也有一个非常好的图表来帮助你查看信息,参见下面的例子:
感谢资源在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();
}
}
你可以试试ACRA (Android应用程序崩溃报告)库:
ACRA是一个库,使Android应用程序自动张贴他们的崩溃报告到GoogleDoc的形式。它是针对android应用程序开发人员,帮助他们从他们的应用程序崩溃或行为错误时获取数据。
它很容易安装在你的应用程序中,高度可配置,不需要你在任何地方托管服务器脚本…报告被发送到谷歌文档电子表格!
你可以直接在Android Studio中做到这一点。只要连接你的手机,运行应用程序,让它崩溃,你就可以直接在Android Studio中查看堆栈跟踪。
我在这里做了我自己的版本: http://androidblogger.blogspot.com/2009/12/how-to-improve-your-application-crash.html
这基本上是相同的事情,但我使用邮件而不是http连接来发送报告,更重要的是,我添加了一些信息,如应用程序版本,操作系统版本,手机型号,或可用内存到我的报告…
推荐文章
- 警告:API ' variable . getjavacompile()'已过时,已被' variable . getjavacompileprovider()'取代
- 安装APK时出现错误
- 碎片中的onCreateOptionsMenu
- TextView粗体通过XML文件?
- 如何使线性布局的孩子之间的空间?
- DSL元素android.dataBinding。enabled'已过时,已被'android.buildFeatures.dataBinding'取代
- ConstraintLayout:以编程方式更改约束
- PANIC: AVD系统路径损坏。检查ANDROID_SDK_ROOT值
- 如何生成字符串类型的buildConfigField
- Recyclerview不调用onCreateViewHolder
- Android API 21工具栏填充
- Android L中不支持操作栏导航模式
- 如何在TextView中添加一个子弹符号?
- PreferenceManager getDefaultSharedPreferences在Android Q中已弃用
- 在Android Studio中创建aar文件