我们写程序的时候都希望能写出一个没有任何Bug的程序,期望在任何情况下都不会发生程序崩溃。不过理想是丰满的,现实是骨感的。没有一个程序员能保证自己写的程序绝对不会出现异常崩溃。特别是针对用户数达到几十万几百万的程序,当你用户数达到一定数量级后,就算你的程序出现个别异常崩溃情况也不用惊讶。
既然我们写的程序都有可能发生异常崩溃,如果是还没发布的程序,我们可以通过测试抓取Log来分析。不过针对已经发布的程序,我们没法重现现象,所以让用户反馈程序异常信息就很重要。下面我们说说如何收集程序运行过程的异常信息。
(PS:新建的,有兴趣可以加入一起讨论:Android群:322599434)
1、Android异常捕获接口
//当线程因未捕获的异常而突然终止时,调用处理程序的接口
static interface UncaughtExceptionHandler
2、设置线程捕获异常
从上面的接口我们可以看到,这个接口是针对线程来说,也就是说我们如果需要监控某个线程运行情况,只要把这个接口实现了,然后把监控方法设置到具体的线程里面即可。一般来说,我们最需要监控的就是我们的UI线程也就是主线程。
//设置当线程由于未捕获到异常而突然终止,并且没有为该线程定义其他处理程序时所调用的默认处理程序。
static void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)
3、UncaughtExceptionHandler实例
//Edited by mythou
//http://www.cnblogs.com/mythou/
public class MythouCrashHandler implements UncaughtExceptionHandler
{
private static final String TAG = "MythouCrashHandler---->";
private UncaughtExceptionHandler defaultUEH;
//构造函数,获取默认的处理方法
public MythouCrashHandler()
{
this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
}
//这个接口必须重写,用来处理我们的异常信息
@Override
public void uncaughtException(Thread thread, Throwable ex)
{
final Writer result = new StringWriter();
final PrintWriter printWriter = new PrintWriter(result);
//获取跟踪的栈信息,除了系统栈信息,还把手机型号、系统版本、编译版本的唯一标示
StackTraceElement[] trace = ex.getStackTrace();
StackTraceElement[] trace2 = new StackTraceElement[trace.length+3];
System.arraycopy(trace, 0, trace2, 0, trace.length);
trace2[trace.length+0] = new StackTraceElement("Android", "MODEL", android.os.Build.MODEL, -1);
trace2[trace.length+1] = new StackTraceElement("Android", "VERSION", android.os.Build.VERSION.RELEASE, -1);
trace2[trace.length+2] = new StackTraceElement("Android", "FINGERPRINT", android.os.Build.FINGERPRINT, -1);
//追加信息,因为后面会回调默认的处理方法
ex.setStackTrace(trace2);
ex.printStackTrace(printWriter);
//把上面获取的堆栈信息转为字符串,打印出来
String stacktrace = result.toString();
printWriter.close();
Log.e(TAG, stacktrace);
//这里把刚才异常堆栈信息写入SD卡的Log日志里面
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
{
String sdcardPath = Environment.getExternalStorageDirectory().getPath();
writeLog(stacktrace, sdcardPath + "/mythou");
}
defaultUEH.uncaughtException(thread, ex);
}
//写入Log信息的方法,写入到SD卡里面
private void writeLog(String log, String name)
{
CharSequence timestamp = DateFormat.format("yyyyMMdd_kkmmss", System.currentTimeMillis());
String filename = name + "_" + timestamp + ".log";
try
{
FileOutputStream stream = new FileOutputStream(filename);
OutputStreamWriter output = new OutputStreamWriter(stream);
BufferedWriter bw = new BufferedWriter(output);
//写入相关Log到文件
bw.write(log);
bw.newLine();
bw.close();
output.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
上面就是实现了获取处理跟踪信息的方法,上面的方法是参照VLC的异常处理机制编写的。做了一些简单修改。不过上面只是获取了异常信息,如果程序安装到用户机器上,我们没法获取到这些信息,总不能让用户把机器拿过来给你,然后你把Log拷贝出来吧。(这个我以前做嵌入式的时候到试过,让客户把机器拿过来,拷贝里面的Log,那时候做的机器无法联网。现在想起来都纠结,O(∩_∩)O哈哈~) 为了不再纠结,我们需要一个可以把Log发送到我们服务器的功能,下面是把一个服务信息发送到我们指定服务器功能。
3、通过网络发送Log
//Edited by mythou
//http://www.cnblogs.com/mythou/
public class SendCrashLog extends AsyncTask<String, String, Boolean>
{
public SendCrashLog() { }
@Override
protected Boolean doInBackground(String... params)
{
if (params[0].length() == 0)
return false;
HttpClient httpClient = new DefaultHttpClient();
//你的服务器,这里只是举个例子。把异常信息当作http请求发送到服务器
HttpPost httpPost = new HttpPost("http://www.mythou/getlog.php");
//这里把相关的异常信息转为http post请求的数据参数
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("model", params[0]));
nameValuePairs.add(new BasicNameValuePair("device", params[1]));
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
//发送相关请求信息
httpClient.execute(httpPost);
} catch (ClientProtocolException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
Log.d(TAG, "Device model sent.");
return true;
}
@Override
protected void onPostExecute(Boolean result) {
}
}
上面就是我上一篇文章讲的异步任务的使用,我们在异步任务里面编写了一个发送http请求的服务,用来把相关的异常信息发送到我们指定的服务器上面。这个需要你的服务器解析发送的http请求,这个难度不大,一般做个web的人都知道如何做。在上面的异常处理里面再调用这里的发送方法:
//Edited by mythou
//http://www.cnblogs.com/mythou/
SendCrashLogsendLog = new SendCrashLog();
//刚才的异常信息字符串
sendLog .execute(stacktrace);
通过上面的方法就可以把异常信息发送到指定的服务器,也就可以跟踪客户使用软件的情况,方便我们修改程序的问题。当然这个信息收集一般都隐私和后台流量问题,这个需要在程序里面做点提示,免得背上流氓软件的骂名。
分享到:
相关推荐
我们写程序的时候都希望能写出一个没有任何Bug的程序,期望在任何情况下都不会发生程序崩溃。不过理想是丰满的,现实是骨感的。没有一个程序员能保证自己写的程序绝对不会出现异常崩溃。特别是针对用户数达到几十万...
android-crash, [DEPRECATED] android程序崩溃异常处理框架
andorid手机程序错误信息的demo.rar android app异常收集处理.rar android java 通用代码,关于用properties存储打印的Log.zip android 错误收集工具.rar android 错误日志的收集.rar Android下的自定义日志...
一个demo,收集Android程序的崩溃日志,保存到SD卡中
android程序奔溃异常收集 [注:本内容来自网络,在此分享仅为帮助有需要的网友,如果侵犯了您的权利,麻烦联系我,我会第一时间删除,谢谢您。]
Bugsnag的库可自动检测Android应用程序中的崩溃,收集诊断信息并立即通知您的开发团队,从而帮助您尽快理解和解决问题。 产品特点 自动报告未处理的异常和崩溃 报告 崩溃报告所附的,并深入了解用户的操作 以确定...
acra服务器用于收集您的 android 应用程序崩溃数据的服务器当前功能关于新崩溃的电子邮件通知将类似的崩溃分组为“问题” 带有一些统计数据的所有应用程序的仪表板具有一些统计信息的单个应用程序的仪表板演示有一个...
android app异常收集处理.rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
Android系统碎片化造成应用程序崩溃严重,在模拟器上运行良好的程序安装到某款手机上说不定就会出现崩溃的现象。而且,往往都是程序发布之后在用户端出现了崩溃现象。所以,如何及时捕获并收集Android平台的崩溃就...
android 错误收集工具.rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
适用于Android的Bugsnag异常报告器Bugsnag的Android故障报告库可自动检测您的Android应用程序中的崩溃,收集诊断信息并立即通知您的开发团队,从而帮助y适用于Android的Bugsnag的异常报告器Bugsnag的Android故障报告...
在开发过程中,虽然经过测试,但在发布后,在广大用户各种各样的运行环境和操作下,可能会发生一些异想不到的错误导致程序崩溃。将这些错误信息收集起来并反馈给开发者,对于开发者改进优化程序是相当重要的。好了,...
开发者应该及时获取在该设备上导致崩溃的信息,这对于下一个版本的bug修复帮助极大,所以今天就来介绍一下如何在程序崩溃的情况下收集相关的设备参数信息和具体的异常信息,并发送这些信息到服务器供开发者分析和...
对于还没发布的应用程序,我们可以通过测试、分析Log的方法来收集崩溃信息。但对已经发布的程序,我们不可能让用户去查看崩溃信息然后再反馈给开发者。所以,设计一个对于小白用户都可以轻松实现反馈的应用就显得...
这类工具通常会捕获系统的各种日志信息,包括但不限于应用程序崩溃日志、系统事件日志、调试输出等。它们可能提供一种用户界面,用于浏览和筛选日志信息,以便开发人员对设备在离线状态下的行为进行分析和故障排查。...
>应用崩溃是影响用户体验的罪魁祸首, 崩溃分析从崩溃收集与统计、异常分析等角度去分析如何构建一个健壮的app。 竞品技术 >所谓竞品, 通常意义上指的是同行竞争对手的产品, 但这种定义比较狭隘, 竞品可以理解为各家...
/res/raw不参加编译的资源,不能生 成对应文件) AndroidManifest.xml 清单文件(声明应用程序属性信息,声明组件,声明权限,唯一一个组件BroadcastRec eiver不需在AndroidManifest中注册) (4)四大组件及其常用...
崩溃报告:如果您的应用程序崩溃,则会将崩溃日志写入设备的存储中。 如果用户再次启动应用程序,他们将被要求向 HockeyApp 提交崩溃报告。 这适用于测试版和实时应用程序,即提交到 Google Play 或其他应用程序商店...
丰富的应用生态系统:Android系统拥有庞大的应用程序生态系统,用户可以从Google Play商店或其他第三方应用市场下载和安装各种各样的应用程序,满足各种需求。 可定制性:Android操作系统可以根据用户的个人喜好进行...