(二)如何保證應用永不崩潰

不囉嗦直接上代碼,你們請看

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是一個阻塞方法的特性,咱們能夠給它外面套上一層無限循環,一旦出錯就會從新啓動輪詢。bash

若是想了解Thread.setDefaultUncaughtExceptionHandler爲何能夠阻止應用crash,能夠查看前一篇文章markdown

經過Thread.setDefaultUncaughtExceptionHandler阻止程序崩潰的源碼解析ide

最後關於handleException的處理

因爲各個公司對錯誤信息處理級別不一樣,針對錯誤數據的封裝也會各不同,我只是提一點我的小建議和心得。oop

1.把錯誤信息作相應的拆分和拼裝,生成規定格式的錯誤數據,寫入日誌文件,日誌文件能夠是區間日誌也能夠是即刻日誌(由於錯誤信息要分等級,若是是重大bug須要及時上傳,並經過短信和郵件及時通知開發人員)post

2.存儲當前設備信息(用戶,廠商,系統,版本)到錯誤日誌性能

3.既然本地有錯誤日誌確定要上傳,不過上傳的間隔確定要控制,畢竟上傳耗費性能(看大家後臺須要刷新錯誤日誌的間隔,)spa

4.上傳完成記得及時清除線程

5.後臺構建錯誤監控模塊(不單單針對應用的bug也有多是部分接口功能異常等),針對重大bug,對應用bug功能及時進行動態屏蔽(對應用內部的功能作接口控制),而後用熱修復或者應用更新解決問題。日誌

相關文章
相關標籤/搜索