• APP全局异常捕获,并保存本地文件


      1 public class CrashHandler implements Thread.UncaughtExceptionHandler {
      2 
      3     public static final String TAG = "CrashHandler";
      4 
      5     // 系统默认的UncaughtException处理类
      6     private Thread.UncaughtExceptionHandler mDefaultHandler;
      7     // CrashHandler实例
      8     private static CrashHandler INSTANCE = new CrashHandler();
      9     // 程序的Context对象
     10     private Context mContext;
     11 
     12     //用来存储设备信息和异常信息
     13     private Map<String, String> infos = new HashMap<String, String>();
     14 
     15     //用于格式化日期,作为日志文件名的一部分
     16     private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
     17 
     18     /**
     19      * 保证只有一个CrashHandler实例
     20      */
     21     private CrashHandler() {
     22     }
     23 
     24     /**
     25      * 获取CrashHandler实例 ,单例模式
     26      */
     27     public static CrashHandler getInstance() {
     28         return INSTANCE;
     29     }
     30 
     31     /**
     32      * 初始化
     33      * @param context
     34      */
     35     public void init(Context context) {
     36         mContext = context;
     37         // 获取系统默认的UncaughtException处理器
     38         mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
     39         // 设置该CrashHandler为程序的默认处理器
     40         Thread.setDefaultUncaughtExceptionHandler(this);
     41     }
     42 
     43     /**
     44      * 当UncaughtException发生时会转入该函数来处理
     45      */
     46     @Override
     47     public void uncaughtException(Thread thread, Throwable ex) {
     48         // ToastUtil.show(mContext, ex.getMessage());
     49         if (!handleException(ex) && mDefaultHandler != null) {
     50             // 如果用户没有处理则让系统默认的异常处理器来处理
     51             mDefaultHandler.uncaughtException(thread, ex);
     52         } else {
     53             try {
     54                 Thread.sleep(500);
     55             } catch (InterruptedException e) {
     56                 Log.e(TAG, "error : ", e);
     57             }
     58             // 退出程序
     59             android.os.Process.killProcess(android.os.Process.myPid());
     60             System.exit(1);
     61 //            KJActivityStack.create().AppExit(mContext);// 结束整个应用程序
     62         }
     63     }
     64 
     65     /**
     66      * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
     67      * @param ex
     68      * @return true:如果处理了该异常信息;否则返回false.
     69      */
     70     private boolean handleException(Throwable ex) {
     71         if (ex == null) {
     72             return false;
     73         }
     74         // 使用Toast来显示异常信息
     75         new Thread() {
     76             @Override
     77             public void run() {
     78                 Looper.prepare();
     79                 Toast.makeText(mContext, "很抱歉,程序出现异常,即将退出.", Toast.LENGTH_LONG).show();
     80                 Looper.loop();
     81             }
     82         }.start();
     83         //保存日志文件
     84         String path = saveCrashInfo2File(ex);
     85         return true;
     86     }
     87 
     88     /**
     89      * 保存错误信息到文件中
     90      * @param ex
     91      * @return 返回文件名称, 便于将文件传送到服务器
     92      */
     93     private String saveCrashInfo2File(Throwable ex) {
     94         infos = PhoneUtils.collectDeviceInfo(mContext);
     95         StringBuffer sb = new StringBuffer();
     96         for (Map.Entry<String, String> entry : infos.entrySet()) {
     97             String key = entry.getKey();
     98             String value = entry.getValue();
     99             sb.append(key + "=" + value + "
    ");
    100         }
    101         Writer writer = new StringWriter();
    102         PrintWriter printWriter = new PrintWriter(writer);
    103         ex.printStackTrace(printWriter);
    104         Throwable cause = ex.getCause();
    105         while (cause != null) {
    106             cause.printStackTrace(printWriter);
    107             cause = cause.getCause();
    108         }
    109         printWriter.close();
    110         String result = writer.toString();
    111         sb.append(result);
    112         FileOutputStream fos = null;
    113         try {
    114             long timestamp = System.currentTimeMillis();
    115             String time = formatter.format(new Date());
    116             String fileName = "crash-" + time + "-" + timestamp + ".log";
    117             if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
    118                 String path = "/sdcard/aaaaaaaaaaaaaaaaaaaaacrash/";
    119 //                String path = mContext.getCacheDir() + "/crash/";
    120                 File dir = new File(path);
    121                 if (!dir.exists()) {
    122                     dir.mkdirs();
    123                 }
    124                 fos = new FileOutputStream(path + fileName);
    125                 fos.write(sb.toString().getBytes());
    126             }
    127             return fileName;
    128         } catch (Exception e) {
    129             Log.e(TAG, "an error occured while writing file...", e);
    130         } finally {
    131             try {
    132                 if (fos != null)
    133                     fos.close();
    134             } catch (IOException e) {
    135                 Log.e(TAG, "an error occured while fos.close...", e);
    136             }
    137         }
    138         return null;
    139     }
  • 相关阅读:
    数据结构 -- 栈(一)
    数据结构 -- 栈(二)
    Linux 静态库 & 动态库
    Python及Pycharm安装详细教程
    Makefile研究(三) —— 实际应用
    Makefile研究(二)—— 完整可移植性模板
    Makefile研究 (一)—— 必备语法
    JSON 下 -- jansson 示例
    C语言中的static 详细分析
    Linux 命令 -- tar
  • 原文地址:https://www.cnblogs.com/androidsj/p/4851338.html
Copyright © 2020-2023  润新知