全局手动捕获崩溃异常错误CrashHandler【工具类直接可用】

85 篇文章 0 订阅
67 篇文章 2 订阅

废话不多哔哔,直接上工具类

/**
 * 全局捕获异常
 * 当程序发生Uncaught异常的时候,有该类来接管程序,并记录错误日志
 */
public class CrashHandler_Ma {
    public static String TAG = "MyCrash";
    // 用来存储设备信息和异常信息
    private static Map<String, String> map = new HashMap<>();

    //使用volatile关键字保其可见性
    volatile private static CrashHandler_Ma instance = null;

    private CrashHandler_Ma() {
    }

    public static CrashHandler_Ma getInstance() {
        try {
            if (instance != null) {//懒汉式

            } else {
                //创建实例之前可能会有一些准备性的耗时工作
                Thread.sleep(300);
                synchronized (CrashHandler_Ma.class) {
                    if (instance == null) {//二次检查
                        instance = new CrashHandler_Ma();
                    }
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return instance;
    }

    public void init(Context context) {
        // 设置该CrashHandler为程序的默认处理器
        Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread thread, Throwable ex) {
                try {
                    Log_Ma.e(TAG, "uncaughtException: " + ex);
                    if (ex != null) {
                        // 使用Toast来显示异常信息
                        /*new Thread() {
                            @Override
                            public void run() {
                                Looper.prepare();
                                Toast.makeText(context, "APP运行缓慢,自动调整中。", Toast.LENGTH_LONG).show();
                                Looper.loop();
                            }
                        }.start();*/

                        saveCrashInfoFile(ex, context);

                        SystemClock.sleep(1000);
                        restartApp();
                    }
                } catch (Exception e) {
                    SystemClock.sleep(1000);
                    // 退出程序
                    android.os.Process.killProcess(android.os.Process.myPid());
                    System.exit(1);
                }
            }
        });
    }

    /**
     * 保存错误信息到文件中
     *
     * @return 返回文件名称, 便于将文件传送到服务器
     */
    private void saveCrashInfoFile(Throwable ex, Context context) {
        try {
            map.put("versionName", AppUtils_Ma.getVersionName(context));
            map.put("versionCode", AppUtils_Ma.getVersionCode(context) + "");
            /*收集设备参数信息*/
            Field[] fields = Build.class.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                map.put(field.getName(), field.get(null).toString());
            }
        } catch (Exception e) {

        }

        StringBuffer sb = new StringBuffer();
        try {
            SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String date = sDateFormat.format(new Date());
            sb.append("\r\n" + date + "\n");
            for (Map.Entry<String, String> entry : map.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                sb.append(key + "=" + value + "\n");
            }
            Writer writer = new StringWriter();
            PrintWriter printWriter = new PrintWriter(writer);
            ex.printStackTrace(printWriter);
            Throwable cause = ex.getCause();
            while (cause != null) {
                cause.printStackTrace(printWriter);
                cause = cause.getCause();
            }
            printWriter.flush();
            printWriter.close();
            String result = writer.toString();
            sb.append(result);

            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
                ActivityManager activityManager = (ActivityManager) App.getContext().getSystemService(Context.ACTIVITY_SERVICE);
                ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo();
                activityManager.getMemoryInfo(info);
                long mm = 1024 * 1024;
                sb.append("\n应用在本机能够获取的最大内存:" + DoubleUtil.div(Runtime.getRuntime().maxMemory(), mm, 2) + "m")
                        .append("\n系统剩余内存: " + DoubleUtil.div(info.availMem, mm, 2) + "m")
                        .append("\n系统是否处于低内存运行:" + info.lowMemory)
                        .append("\n系统总的内存:" + DoubleUtil.div(info.totalMem, mm, 2) + "m")
                        .append("\n临界值,达到这个值,进程就要被杀死:" + DoubleUtil.div(info.threshold, mm, 2) + "m");
            }
        } catch (Exception e) {
            sb.append("an error occured while writing file...\r\n");
        }
        LiteOrmDBUtil.insert(new Bean_ERROR(0, sb.toString()));
        sb.setLength(0);
    }

    /*重启应用(按需要添加是否重启应用)*/
    public void restartApp() {
        ActivityManager_Singe.getInstance().finishAllActivity();
        Intent intent = new Intent(App.getContext(), Activity_Splash.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        App.getContext().startActivity(intent);
        android.os.Process.killProcess(android.os.Process.myPid());
    }
}

使用方法:

        在Application里面的onCreate()方法里添加

CrashHandler_Ma.getInstance().init(this);

 其实里面有一个这个方法:LiteOrmDBUtil.insert(new Bean_ERROR(0, sb.toString()));

我其实是把这个错误信息保存到数据库里面了,等到下次进首页的时候,把数据库里面的错误信息传到服务器,便于后续分析,这也是常用的一种手段,还有一些人集成第三方,也可以,这里只讲手动的步骤。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值