UncaughtExceptionHandler的使用

来源:互联网 发布:cxf webservice json 编辑:程序博客网 时间:2024/06/07 06:43

       当我们在执行android程序时避免不了出现crash 等异常. 这个时候我们只能将被迫去找crash的log,比如控制台的打印.而我们想要实时的想看这样的log,该如何做呢?

       今天有时间研究了一下UncaughtExceptionHandler的功能.

       异常分为检测异常和未检测异常,不管是什么异常,我们都可以主动的处理异常,比如我们在捕获异常后做相应的处理.

       往往我们通过try {)catch(Exception e){e.printStackTrace()}处理,打印异常.  或者直接调用log方法输出异常信息.

  1.      StringWriter sw = new StringWriter();  
  2.             PrintWriter pw = new PrintWriter(sw);  
  3.             e.printStackTrace(pw);  
  4.             return "\r\n" + sw.toString() + "\r\n";  


但是我们经常会碰到偶现的bug,此时不能实时的分析其原因,此时我们可以将异常写入文件.此时我们可以注册UncaughtExceptionHandler方法,起可以通过uncaughtException来捕获.

比如专车里面的异常捕获,继承UncaughtExceptionHandler

注意的是 ,通过Thread.setDefaultUncaughtExceptionHandler()方法将异常处理类设置到线程上即可.

ZCCrashHandler implements UncaughtExceptionHandler {

private Thread.UncaughtExceptionHandler mDefaultHandler;
 private static ZCCrashHandler INSTANCE;

 private ZCCrashHandler() {
 }

 public static ZCCrashHandler getInstance() {
  if (INSTANCE == null)
   INSTANCE = new ZCCrashHandler();
  return INSTANCE;
 }

 public void onDestory() {
  mDefaultHandler = null;
  INSTANCE = null;
 }
 
 public void init(Context ctx) {
  mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
  Thread.setDefaultUncaughtExceptionHandler(this);
 }

 @Override
 public void uncaughtException(Thread thread, Throwable ex) {
  final String msg = getCrashInfoToFile(ex);
  if (ZCConfig.IS_DEBUG) {
   new Thread(new Runnable() {
    
    @Override
    public void run() {
     recordCrashLog(msg);
    }
   }).start();
  }
  if (mDefaultHandler != null) {
   mDefaultHandler.uncaughtException(thread, ex);
  }


 }
 
 
 public void recordCrashLog(final Throwable ex) {
  new Thread(new Runnable() {

   @Override
   public void run() {
    String msg = getCrashInfoToFile(ex);
    recordCrashLog(msg);
   }
  }).start();
 }

 private void recordCrashLog(final String msg) {
  try {
//   File f = Environment.getExternalStorageDirectory();
   File carLog = new File(ZCConfig.LOG_DIR_DIR, ZCConfig.CRASH_NAME);
   if (!carLog.exists()) {
    carLog.createNewFile();
   }
   FileWriter fw = new FileWriter(carLog, true);
   fw.write(msg);
   fw.flush();
   fw.close();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
 
 private String getCrashInfoToFile(Throwable ex) {
  if (ex == null) {
   return null;
  }
  StringWriter info = null;
  PrintWriter printWriter = null;
  try {
   info = new StringWriter();
   printWriter = new PrintWriter(info);
   ex.printStackTrace(printWriter);
   Throwable cause = ex.getCause();
   while (cause != null) {
    cause.printStackTrace(printWriter);
    cause = cause.getCause();
   }
   return info.toString();
  } catch (Exception e) {
   e.printStackTrace();
   return null;
  } finally {
   try {
    if (printWriter != null) {
     printWriter.close();
    }
    if (info != null) {
     info.close();
    }
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
 }

}

在调用时,使用ZCCrashHandler.getInstance().init(this);即可.当有异常时会在uncaughtException(Thread thread, Throwable ex) 中处理,将异常写入文件.

所用到的常量: public static final String LOG_DIR_DIR = APP_DIR + File.separator + LOG_DIR_NAME;

 public static final String APP_DIR = Environment.getExternalStorageDirectory().toString() + File.separator + APP_DIR_NAME;

 public static final String APP_DIR_NAME = "ucar";

 public static final String LOG_DIR_NAME = "log";

 public static final String CRASH_NAME = "crash.txt";


0 0
原创粉丝点击