1. 程式人生 > >Android CrashHandler 自定義崩潰異常捕獲

Android CrashHandler 自定義崩潰異常捕獲

當APP 異常崩潰時,使用Toast提示,並關閉APP,收集錯誤資訊儲存並上報

需求:由於android機型的碎片化,我們在開發時無法對所以機型進行測試,因此在可能的崩潰發生時,我們應當做一些事情來為我們提供更多資訊以便改進,同時也能然崩潰發生時的使用者體驗得到一些改善。例如程式崩潰後的重啟APP、系統dialog等並不為我們想要,因此可以在APP崩潰時進行一些處理。由於現在一些第三方提供的崩潰日誌的捕獲上傳做得也不錯,對於類似我們這些中小型公司,可以整合如騰訊的Bugly、百度的測試雲平臺等第三方SDK進行崩潰日誌的收集及上傳,在我們自定義的CrashHandler裡做一些互動處理即可。如使用Toast進行崩潰提示、在崩潰時關掉APP避免重啟。

步驟

  • 建立CrashHandler類,繼承UncaughtExceptionHandler 介面
  • 編寫崩潰處理邏輯
  • 在自定義application中註冊CrashHandler

程式碼塊

public class CrashHandler implements Thread.UncaughtExceptionHandler {

    private static CrashHandler instance = new CrashHandler();
    private Context mContext;

    private CrashHandler() {}

    public
static CrashHandler getInstance() { return instance; } public void setCustomCrashHanler(Context context) { mContext = context; //崩潰時將catch住異常 Thread.setDefaultUncaughtExceptionHandler(this); } //崩潰時觸發 @Override public void uncaughtException(Thread thread, Throwable ex) { //使用Toast進行提示
showToast(mContext, "很抱歉,程式異常即將退出!"); //延時退出 try { thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } //關閉APP Util.exic(); } //執行緒中展示Toast private void showToast(final Context context, final String msg) { new Thread(new Runnable() { @Override public void run() { Looper.prepare(); Toast.makeText(context, msg, Toast.LENGTH_LONG).show(); Looper.loop(); } }).start(); } }

在自定義Application的onCreate()函式中註冊CrashHandle.

 @Override
    public void onCreate() {
        super.onCreate();
            CrashHandler crashHandler = CrashHandler.getInstance();
            crashHandler.setCustomCrashHanler(getApplicationContext());
            ......
        }

如果是首次自定義Application,別忘了在AndroidManifest.xml中註冊。

<application
        android:name=".MyApplication"
        ......

自定義工具類,關閉所有activity以關閉APP。

public class Util {

    public static List<Activity> activityList = new LinkedList<Activity>();

     public static void addActivity(Activity activity) {
        activityList.add(activity);
    }

    public static void removeActivity(Activity activity) {
        if (activityList != null) {
            boolean bResult = activityList.remove(activity);
            while (bResult) {
                bResult = activityList.remove(activity);
            }
        }
    }

    public static void exic(){
         if (activityList.size() > 0) {
            for (Activity activitys : MyActivity.activityList) {
                try {
                    activitys.finish();
                } catch (Exception e) {
                }
            }
        }
        System.exit(0);
    }
}

在自定義的activity基類的onCreate()和onDestroy()中呼叫。

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Util.addActivity(this);
        ......
    }

    @Override
    protected void onDestroy() {
        removeActivity(_this);
        ......
        super.onDestroy();
    }

最後在程式的一處寫個異常如 int i=1/0; 執行到那裡進行異常測試。