Android 如何收集已发布程序的崩溃信息

2016-02-19 09:03 5 1 收藏

下面是个超简单的Android 如何收集已发布程序的崩溃信息教程,图老师小编精心挑选推荐,大家行行好,多给几个赞吧,小编吐血跪求~

【 tulaoshi.com - 编程语言 】

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

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

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

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 AsyncTaskString, 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 {
                ListNameValuePair nameValuePairs = new ArrayListNameValuePair(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);

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

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

来源:http://www.tulaoshi.com/n/20160219/1589346.html

延伸阅读
赶集生活如何发布拼车信息   1)首先先打开进去之后点击。   2)然后点击右上角的,最后输入拼车信息点击就可以了。  
微信Android新版发布   在智能机时代,微信已经迅速成为国内主流社交软件,今天官方正式发布了面向Android平台的新版微信应用,版本号5.2.1。 其一是用户在发朋友圈时,可以附上你所在的餐馆或景点,让自己分享的信息更加全面。 其二,则是一项非常实用且重要的功能,允许用户将自己的维信聊天记录通过腾讯电脑管家...
标签: SQLServer
  问:我需要在运行SQL Server的机器上定期收集诸如每秒处理事务数(tps)之类的统计信息。为此,我大量使用了Performance Monitor(性能监视器),但却不能得到DBA所需的SQL Server性能指标。请问是否存在能够轻松收集这类统计信息的实用工具? 答:针对SQL Server的Performance Monitor计数器之一便能收集tps,因此,使用Performance M...
全球民宿预订如何发布出租信息   1)打开自己的全球民宿预订,然后点击右上角选择   2)选择自己要发布空间类型,根据自己房屋选择房源   3)填写你所要组房屋城市,然后填写更详细的房屋设施点击即可完成           注 :更多精彩教程请关注图老师手机教程栏目...
iPhone如何快速将信息标记为已读 在ios6版的iphone5中,每收到一封邮件,都会在未读邮件中增加一个数字,以提示你有多少个邮件没有查看了。在这些邮件中通常有很多无用的垃圾邮件,并不想一一查看,但若不查看,未读邮件的数字就没有变化,可能会影响到重要邮件的查看。 在iphone5升级到ios7后,会发现这一状况得到了极大的改进,在...

经验教程

410

收藏

7
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部