實現UncaughtExceptionHandler來實現獲取應用全域性的crash資訊
Android應用不可避免的會出現各種崩潰crash,平時我們可能會通過try-catch來捕獲異常,可是我們總不可能每一段程式碼都try-catch,所以我們還是會有很多捕獲不到的異常,而且一旦應用釋出後,在客戶端出現的問題我們也不能debug除錯,也沒有logcat了,客戶端崩潰後用戶體驗很不好,但是我們因為捕獲不到相關異常資訊想要修復程式也顯得有心無力,其實Android是提供了一個可以設定的全域性異常捕獲方法,就是Thread.setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler
handler)
他的英文註解是:
/**
* Sets the default uncaught exception handler. This handler is invoked in
* case any Thread dies due to an unhandled exception.
*
* @param handler
* The handler to set or null.
*/
大概意思就是設定預設未捕獲的異常處理handler,這個handler可以在任意執行緒被未處理的異常喚醒。也就是說只要你的程式發生了沒被處理的異常就會呼叫這個handler來處理異常,是不是感覺很厲害。
使用方法:
1.寫一個類實現UncaughtExceptionHandler介面,實現uncaughtException方法;
2.每次發生異常會自動呼叫uncaughtException方法,所以在這裡寫出你希望發生錯誤時的處理方法,例如把錯誤資訊上傳伺服器或者寫到本地磁碟檔案或者彈出dialog提示使用者等。
3.在你的程式一執行就初始化這個類,所以一般都是在application裡初始化這個類。
demo效果:
程式碼解析:
public class CrashHandler implements Thread.UncaughtExceptionHandler { private staticCrashHandler crashHandler = new CrashHandler(); private Context mContext; private Thread.UncaughtExceptionHandler mDefaultCaughtExceptionHandler; //使用餓漢單例模式 public static CrashHandler getInstance() { return crashHandler; } public void init(Context context) { //獲取預設的系統異常捕獲器 mDefaultCaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); //把當前的crash捕獲器設定成預設的crash捕獲器 Thread.setDefaultUncaughtExceptionHandler(this); mContext = context.getApplicationContext(); } @Override public void uncaughtException(Thread thread, Throwable ex) { //注意需要清空所有已經啟動的activity,否則你的錯誤提示框可能會彈出很多次 MyApplication.clearActivity(); //啟動錯誤處理頁面,你也可以在這裡寫上傳伺服器什麼的 Intent intent = new Intent("com.crash.start"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.putExtra("message",ex.getMessage()); mContext.startActivity(intent); Process.killProcess(Process.myPid());//殺掉程序 /*我看網上不少栗子是下面這麼寫的,但是實際測試的結果是,Android6.0以上的系統這麼寫沒有任何問題, 但如果是6.0以下的系統主執行緒異常這樣寫也沒有問題, * 但如果6.0以下系統並且異常出現在子執行緒中,這麼寫就會執行系統那個醜陋的白色程式異常停止執行的提示框, * 然後點選確定後直接退出程式,不會執行你希望的友好退出介面*/ // if (mDefaultCaughtExceptionHandler != null) { // mDefaultCaughtExceptionHandler.uncaughtException(thread,ex); // } else { // Process.killProcess(Process.myPid());//殺掉程序 // } } }
在你的application裡初始化這個類:
public class MyApplication extends Application { private static ArrayList<Activity> activities; @Override public void onCreate() { super.onCreate(); activities = new ArrayList<>(); CrashHandler.getInstance().init(this);//初始化全域性異常捕獲器 } /**新增activity*/ public static void addActivity(Activity activity) { activities.add(activity); } /**結束所有被新增的activity*/ public static void clearActivity() { for (Activity activity : activities) { activity.finish(); } } }別忘了去AndroidManifest裡宣告application
<application android:name=".MyApplication"