(二)如何保证应用永不崩溃

1,276 阅读2分钟

不啰嗦直接上代码,大家请看

public class CrashHandlerManager {
    private static CrashHandlerManager instance;
    private static Context mContext;
    private CrashHandlerManager(){}

    public static CrashHandlerManager getInstance(Context context){
        if(instance==null){
            mContext=context.getApplicationContext();
            instance=new CrashHandlerManager();
        }
        return  instance;
    }
    public void init(){
        Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler(){
            @Override
            public void uncaughtException(Thread t, Throwable e) {
                handleException(e);
                //判断当前线程是否是主线程
                if(t== Looper.getMainLooper().getThread()){
                    handleMainThread(e);
                }
            }
        });
    }

    private void handleMainThread(Throwable e) {
        while (true) {
            try {
                Looper.loop();
            } catch (Throwable throwable) {
                handleException(throwable);
            }
        }
    }

    private void handleException(Throwable e) {
        //写入错误日志
        //上传日志
    }
}

大家很容易就看懂了这个类,保证应用永不崩溃关键在于handleMainThread这个方法。一旦主线程中出现异常就会导致Looper.loop无法正常轮询,看过源码的都知道Looper.loop是执行在ActivityThread的main方法中,只会执行一次,而Looper.loop不能正常轮询就会导致应用崩溃。其中利用Looper.loop是一个阻塞方法的特性,我们可以给它外面套上一层无限循环,一旦出错就会重新启动轮询。

如果想了解Thread.setDefaultUncaughtExceptionHandler为什么可以阻止应用crash,可以查看前一篇文章

通过Thread.setDefaultUncaughtExceptionHandler阻止程序崩溃的源码解析

最后关于handleException的处理

由于各个公司对错误信息处理级别不同,针对错误数据的封装也会各不一样,我只是提一点个人小建议和心得。

1.把错误信息做相应的拆分和拼装,生成规定格式的错误数据,写入日志文件,日志文件可以是区间日志也可以是即刻日志(因为错误信息要分等级,如果是重大bug需要及时上传,并通过短信和邮件及时通知开发人员)

2.存储当前设备信息(用户,厂商,系统,版本)到错误日志

3.既然本地有错误日志肯定要上传,不过上传的间隔肯定要控制,毕竟上传耗费性能(看你们后台需要刷新错误日志的间隔,)

4.上传完成记得及时清除

5.后台构建错误监控模块(不仅仅针对应用的bug也有可能是部分接口功能异常等),针对重大bug,对应用bug功能及时进行动态屏蔽(对应用内部的功能做接口控制),然后用热修复或者应用更新解决问题。