關於crash捕獲的那些事

關於crash捕獲的那些事

  Android應用不可避免地會發生crash,也稱之爲奔潰,其可能由於Android系統底層的bug,也可能是由於不充分的機型適配或者是糟糕的網絡狀況。當crash發生時,系統會kill掉正在執行的程序,現象就是閃退或者提示用戶程序已停止執行。
在這裏插入圖片描述
  Android爲了能夠獲取應用的crash信息,提供了一個解決方案。在Thread中有一個方法setDefaultUncaughtExceptionHandler,如下所示。

public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
    // Android-removed: SecurityManager stubbed out on Android
    /*
    SecurityManager sm = System.getSecurityManager();
    if (sm != null) {
        sm.checkPermission(
            new RuntimePermission("setDefaultUncaughtExceptionHandler")
                );
    }
    */

     defaultUncaughtExceptionHandler = eh;
 }

  該方法設置系統的默認異常處理器,當crash發生的時候,系統就會回調UncaughtExceptionHandler的uncaughtException方法。這也就意味着,我們可以在uncaughtException方法中獲取crash異常信息,可以選擇把異常信息存儲到SD卡中,然後再合適的時機通過網絡將crash信息上傳到服務器上(於是我們就可以爲所欲爲了,hhhh)。
在這裏插入圖片描述
  一個典型的異常處理器的實現步驟爲:
  ① 實現一個UncaughtExceptionHandler對象,在它的uncaughtException方法中獲取異常信息並將其存儲在SD卡中或者上傳到服務器供開發人員分析。
  ② 調用Thread的setDefaultUncaughtExceptionHandler方法將它設置爲線程默認的異常處理器。由於默認異常處理器是Thread類的靜態成員,因此它作用對象是當前進程的所有線程
一個典型的異常處理器實現如下所示(筆者簡略了處理異常信息代碼)。

public class CrashHandler implements Thread.UncaughtExceptionHandler {
    
    private static CrashHandler sInstance;
    private Thread.UncaughtExceptionHandler mDefaultCrashHandler;
    private Context mContext;
    
    private CrashHandler() {
    }
    
    public static CrashHandler getInstance() {
        if (sInstance == null) {
            synchronized (CrashHandler.class) {
                if (sInstance == null) {
                    sInstance = new CrashHandler();
                }
            }
        }
        return sInstance;
    }
    
    public void init(Context context) {
        mDefaultCrashHandler = Thread.getDefaultUncaughtExceptionHandler();
        Thread.setDefaultUncaughtExceptionHandler(this);
        mContext = context.getApplicationContext();
    }


    /**
     * 獲取異常信息並處理
     * @param t
     * @param e
     */
    @Override
    public void uncaughtException(@NonNull Thread t, @NonNull Throwable e) {
        // ...
    }
}

  有了CrashHandler之後,只需要在Application初始化的時候爲線程設置CrashHandler即可,如下所示。

public class BaseApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        CrashHandler crashHandler = CrashHandler.getInstance();
        crashHandler.init(this);
    }
}

  這樣只需要對uncaughtException方法進行實現就可以實現目標了。需要注意的是,代碼中被catch的異常不會交給CrashHandler處理,CrashHandler只能接收那些未被捕獲的異常
在這裏插入圖片描述

參考資料:《Android開發藝術探索》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章