展会信息港展会大全

android开发如何收集已发布程序的崩溃信息
来源:互联网   发布日期:2016-01-19 12:16:17   浏览:3096次  

导读:下面我就说说如何收集程序运行过程的异常信息。需要的朋友可以过 来参考下我们写程序的时候都希望能写出一个没有任何Bug的程序,期望在任何情况下都不会发生程序崩溃。不过理想是丰满的,现实是骨感的。没有一个 ...

下面我就说说如何收集程序运行过程的异常信息。需要的朋友可以过 来参考下

我们写程序的时候都希望能写出一个没有任何Bug的程序,期望在任何情况下都不会发生程序崩溃。不过理想是丰满的,现实是骨感的。没有一个程序员能 保证自己写的程序绝对不会出现异常崩溃。特别是针对用户数达到几十万几百万的程序,当你用户数达到一定数量级后,就算你的程序出现个别异常崩溃情况也不用 惊讶。

既然我们写的程序都有可能发生异常崩溃,如果是还没发布的程序,我们可以通过测试抓取Log来分析。不过针对已经发布的程序,我们没法重现现象,所以让用 户反馈程序异常信息就很重要。下面我们说说如何收集程序运行过程的异常信息。

1、Android异常捕获接口

复制代码 代码如下:

//当线程因未捕获的异常而突然终止时,调用处理程序的接口

static interface UncaughtExceptionHandler

2、设置线程捕获异常

从上面的接口我们可以看到,这个接口是针对线程来说,也就是说我们如果需要监控某个线程运行情况,只要把这个接口实现了,然后把监控方 法设置到具体的线程里面即可。一般来说,我们最需要监控的就是我们的UI线程也就是主线程。

复制代码 代码如下:

//设置当线程由于未捕获到异常而突然终止,并且没有为该线程定义其他处理程序时所调用的默认处理程序。

static void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)

3、UncaughtExceptionHandler 实例

复制代码 代码如下:

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

复制代码 代码如下:

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的人都知道如何做。在上面的异常处理里面再调用这里的发送方法:

复制代码 代码如下:

SendCrashLogsendLog = new SendCrashLog();

//刚才的异常信息字符串

sendLog .execute(stacktrace);

通过上面的方法就可以把异常信息发送到指定的服务器,也就可以跟踪客户使用软件的情况,方便我们修改程序的问题。当然这个信息收集一般都隐私和后台流量问 题,这个需要在程序里面做点提示,免得背上流氓软件的骂名。

赞助本站

人工智能实验室

相关热词: 崩溃 android开发

AiLab云推荐
推荐内容
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港