自定义CrashHandler

2020-05-24  本文已影响0人  卡路fly

UncaughtExceptionHandler

为了捕获没有被捕获的异常,包括运行时异常,执行错误(内存溢出等),子线程抛出的异常等。

1. 创建一个类 CrashHandler 实现 UncaughtExceptionHandler 接口 , 当程序发生未捕获异常时 由该类进行处理

public class CrashHandler implements Thread.UncaughtExceptionHandler {

    private Thread.UncaughtExceptionHandler mDefaultHandler;
    Context context;

    //CrashHandler实例
    private static CrashHandler instance;

    /**
     * 获取CrashHandler实例 ,单例模式
     */
    public static CrashHandler getInstance() {
        if (instance == null)
            instance = new CrashHandler();
        return instance;
    }

    /**
     * 初始化
     */
    public void init(Context context) {
        this.context = context;
        //获取系统默认的UncaughtException处理器
        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
        //设置该CrashHandler为程序的默认处理器
        Thread.setDefaultUncaughtExceptionHandler(this);
    }
    
          
          //实现uncaughException方法 

    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        if (!solveException(ex) && mDefaultHandler != null) {
            //如果用户没有处理则让系统默认的异常处理器处理
            mDefaultHandler.uncaughtException(thread, ex);
        } else {
       // 等待2秒钟后关闭程序
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            android.os.Process.killProcess(android.os.Process.myPid());
            System.exit(1);
        }
    }

    /*
     * 错误处理
     * */
    private boolean solveException(Throwable e) {
        if (e == null) {
            return false;
        }
        new Thread() {
            @Override
            public void run() {
                Looper.prepare();
                Toast.makeText(context, "程序出现异常,2秒后退出", Toast.LENGTH_SHORT).show();
                Looper.loop();
            }
        }.start();
        return true;
    }

}

2. 创建一个基础Application的类MApplication

在onCreate()方法中进行初始化

CrashHandler.getInstance().init(getApplicationContext());

多进程可能内存在问题

发生crash后,通过uncaughtException或killApp,只对当前进程进行了重启或杀死,其他进程仍存在。

   /**
     * 杀死除当前进程的其他进程
     */
    @SuppressWarnings("WeakerAccess")
    public static void killProcessExceptCurrent(@NonNull Context context) {
        Log.e(TAG, "killProcessExceptCurrent");
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        if (am == null) {
            return;
        }
        List<ActivityManager.RunningAppProcessInfo> runningApps = am.getRunningAppProcesses();
        if (runningApps == null) {
            return ;
        }
        for (ActivityManager.RunningAppProcessInfo proInfo : runningApps) {
            if (proInfo.processName.startsWith(HiApplication.context.getPackageName())
                    && proInfo.pid != android.os.Process.myPid()) {
                Log.e(TAG, "killProcessExceptCurrent kill:  " + proInfo.processName);
                android.os.Process.killProcess(proInfo.pid);
            }
        }
    }

PS:

https://blog.csdn.net/axi295309066/article/details/56123954

android6.0以上的getRunningAppProcesses也失效,出于安全考虑系统关闭了三方软件对系统进程的访问。

上一篇下一篇

猜你喜欢

热点阅读