返回介绍

5.1 异常收集

发布于 2024-08-17 23:46:12 字数 2812 浏览 0 评论 0 收藏 0

一个健壮的App应该能搜集运行中所有的Crash信息,并将其发送到服务器以便程序员进行分析。

对于任何一款App而言,无论页面数量多少,我们也不可能在每个页面的每个方法都加上try…catch…语句来捕获Crash,而是需要一套统一的解决方案,将Crash一网打尽。

为此我们需要了解一个很重要的类:UncaughtExceptionHandler,用来处理未捕获的异常。未捕获异常指的是在程序中未使用try…catch…语句而抛出的异常。我们需要在App级别处理这些未捕获到的异常,算是最后一道关卡。

如果程序出现了未捕获异常,默认会弹出系统的强制关闭对话框。我们需要实现此接口,并在App中对其进行注册。这样当未捕获异常发生时,就可以做一些个性化的异常处理操作。

于是我们设计一个CrashHandler类,使之继承自UncaughtExceptionHandler,来定义我们自己的异常捕获逻辑,如下所示:

/**
 * UncaughtException处理类


,当程序发生


Uncaught异常的时候


,
 * 由该类来接管程序


,并记录发送错误报告


.
 * 需要在


Application中注册,为了要在程序启动器就监控整个程序。



 */
public class CrashHandler implements UncaughtExceptionHandler {
  public static final String TAG = "CrashHandler";
  public static final String APP_CACHE_PATH = 
       Environment.getExternalStorageDirectory().getPath() 
       + "/YoungHeart/crash/";

我们要实现CrashHandler的uncaughtException方法,详细的代码如下所示:

/**
 * 当


UncaughtException发生时会转入该函数来处理



 */
@Override
public void uncaughtException(Thread thread, Throwable ex) {
  if (!handleException(ex) && mDefaultHandler != null) {
    // 如果用户没有处理则让系统默认的异常处理器来处理



    mDefaultHandler.uncaughtException(thread, ex);
  } else {
    try {
      Thread.sleep(3000);
    } catch (InterruptedException e) {
      Log.e(TAG, "error : ", e);
    }
    // 退出程序



    android.os.Process.killProcess(
        android.os.Process.myPid());
    System.exit(1);
  }
}

这里只介绍其中最关键的方法,也就是handleException方法,这个方法做三件事情:

1)发错误日志到服务器。

2)给用户崩溃前的友好提示。

3)把错误日志记录到SD卡。

其代码如下所示:

/**
 * 自定义错误处理


,收集错误信息


 
 * 发送错误报告等操作均在此完成



 *
 * @param ex
 * @return true:如果处理了该异常信息


;否则返回


false.
 */
private boolean handleException(Throwable ex) {
  if (ex == null) {
    return false;
  }
  // 把


crash发送到服务器



  sendCrashToServer(context, ex);
  // 使用


Toast来显示异常信息



  new Thread() {
    @Override
    public void run() {
      Looper.prepare();
      Toast.makeText(context, 
          "很抱歉


,程序出现异常


,即将退出


.", 
          Toast.LENGTH_SHORT).show();
      Looper.loop();
    }
  }.start();
  // 保存日志文件



  saveCrachInfoInFile(ex);
  return true;
}

sendCrashToServer方法负责将捕获的异常发送到服务器,为此需要MobileAPI提供一个接口。表5-1中的信息都是很重要的,我们要事先准备这些数据。

表5-1 Crash数据表结构

有了上述机制,所有的异常就全都能被捕获到了。但并不是所有的异常都导致崩溃——我们希望尽可能留住用户,而不是App崩溃后重启。因为用户是不会重启打开App的,至少我不会。

有些异常是不严重的。比如说MobileAPI的数据不规范,该返回数值的却返回了字符串,不能为空的字段却返回了空值。这些数据中,有些数据仅仅是为了显示,显示与否无伤大雅,所以即使解析时出了问题抛出异常,也不应该崩溃。我们应该在相应的Activity,在具体解析数据的地方,加一层自定义的try…catch…语句,来捕获这些已知的异常。

需要注意的是,如果异常在Activity中就被捕获到了,就不会将其再交由Application级别的CrashHandler类去处理了。所以我们要在这个Activity的try…catch…语句中,手动把异常信息发送到服务器。在具体的Activity中,我们会将CrashType设置为0,而在CrashHandler中才会将CrashType设置为1。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文