Android解決應用崩潰後重啓的問題,以及與bugly的衝突

在某些手機或者平板上,android程序崩潰後,系統會根據堆棧信息強行把應用重新拉起。但是這種強行重啓應用,會一些數據缺失的問題,造成二次崩潰,這樣的體驗是十分不好的。

所以我的目標就是崩潰後不要重新拉起應用。

如何解決崩潰後重新的問題,可以參見下面的文章,本文不做過多的描述,清空activityStack即可。

Android 解決應用崩潰後重啓的問題 

核心代碼如下:

public class BuglyCrashHandler implements Thread.UncaughtExceptionHandler {

   
    List<Activity> activities = new ArrayList<>();
    static BuglyCrashHandler instance;

    public BuglyCrashHandler(Application application) {
        exceptionHandler = handler;
        registerActivityListener(application);
    }

    @Override
    public void uncaughtException(Thread t, Throwable e) {
        clearAllActivity();
    }

    public void clearAllActivity() {
        for (Activity activity : activities) {
            if (null != activity) {
                activity.finish();
            }
        }
    }

    private void registerActivityListener(Application application) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
                @Override
                public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                    /**
                     *  監聽到 Activity創建事件 將該 Activity 加入list
                     */
                    activities.add(activity);
                }

                @Override
                public void onActivityStarted(Activity activity) {

                }

                @Override
                public void onActivityResumed(Activity activity) {

                }

                @Override
                public void onActivityPaused(Activity activity) {

                }

                @Override
                public void onActivityStopped(Activity activity) {

                }

                @Override
                public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

                }

                @Override
                public void onActivityDestroyed(Activity activity) {
                    if (null == activities && activities.isEmpty()) {
                        return;
                    }
                    if (activities.contains(activity)) {
                        /**
                         *  監聽到 Activity銷燬事件 將該Activity 從list中移除
                         */
                        activities.remove(activity);
                    }
                }
            });
        }
    }
}

application調用如下方法:

Thread.setDefaultUncaughtExceptionHandler(new BuglyCrashHandler(application);

一般這樣做是沒有問題的,但是如果引入了bugly,那就有問題了。bugly也使用的是Thread.setDefaultUncaughtExceptionHandler(this)方式,則只會有一個生效。BuglyCrashHandler會和bugly默認的UncaughtExceptionHandler衝突,這就是本文要解決的重點。

所以我們可以簡單的改一下,使用自定義的UncaughtExceptionHandler,然後在uncaughtException中昨晚自己的事情後,再把異常轉交給bugly的UncaughtExceptionHandler。如下:

public class BuglyCrashHandler implements Thread.UncaughtExceptionHandler {

    Thread.UncaughtExceptionHandler exceptionHandler;
    List<Activity> activities = new ArrayList<>();
    static BuglyCrashHandler instance;

    public BuglyCrashHandler(Application application, Thread.UncaughtExceptionHandler handler) {
        exceptionHandler = handler;
        registerActivityListener(application);
        instance = this;
    }

    @Override
    public void uncaughtException(Thread t, Throwable e) {
       
        if (exceptionHandler != null) {
            exceptionHandler.uncaughtException(t, e);
        }
        clearAllActivity();
         android.os.Process.killProcess(android.os.Process.myPid());
    }

    public void clearAllActivity() {
        for (Activity activity : activities) {
            if (null != activity) {
                activity.finish();
            }
        }
    }

    public static BuglyCrashHandler getInstance() {
        return instance;
    }

    private void registerActivityListener(Application application) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
                @Override
                public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                    /**
                     *  監聽到 Activity創建事件 將該 Activity 加入list
                     */
                    activities.add(activity);
                }

                @Override
                public void onActivityStarted(Activity activity) {

                }

                @Override
                public void onActivityResumed(Activity activity) {

                }

                @Override
                public void onActivityPaused(Activity activity) {

                }

                @Override
                public void onActivityStopped(Activity activity) {

                }

                @Override
                public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

                }

                @Override
                public void onActivityDestroyed(Activity activity) {
                    if (null == activities && activities.isEmpty()) {
                        return;
                    }
                    if (activities.contains(activity)) {
                        /**
                         *  監聽到 Activity銷燬事件 將該Activity 從list中移除
                         */
                        activities.remove(activity);
                    }
                }
            });
        }
    }
}

application中使用方式如下:

注意調用順序,必須在bugly調用之後在調用。

Thread.setDefaultUncaughtExceptionHandler(new BuglyCrashHandler(application, Thread.getDefaultUncaughtExceptionHandler()));

但是實際驗證下來,程序還是會被重新啓動。於是乎,繼續debug驗證,發現bugly的異常處理又阻斷效果。

 @Override
    public void uncaughtException(Thread t, Throwable e) {
        Log.i("lxl", "uncaughtException before:thread:" + Thread.currentThread().getName());
        if (exceptionHandler != null) {
            exceptionHandler.uncaughtException(t, e);
        }
        //後面的代碼都不會被執行
        clearAllActivity();
        android.os.Process.killProcess(android.os.Process.myPid());
        Log.i("lxl", "uncaughtException after");
    }

是懷疑是bugly的異常處理中,應該調用了殺死進程一類的操作,所以導致後面的代碼沒有執行。於是稍微改了下,最終代碼如下,完美解決了程序崩潰後重啓與bugly的衝突。

public class BuglyCrashHandler implements Thread.UncaughtExceptionHandler {

    Thread.UncaughtExceptionHandler exceptionHandler;
    List<Activity> activities = new ArrayList<>();
    static BuglyCrashHandler instance;

    public BuglyCrashHandler(Application application, Thread.UncaughtExceptionHandler handler) {
        exceptionHandler = handler;
        registerActivityListener(application);
        instance = this;
    }

    @Override
    public void uncaughtException(Thread t, Throwable e) {
        clearAllActivity();
        if (exceptionHandler != null) {
            exceptionHandler.uncaughtException(t, e);
        }
    }

    public void clearAllActivity() {
        for (Activity activity : activities) {
            if (null != activity) {
                activity.finish();
            }
        }
    }

    public static BuglyCrashHandler getInstance() {
        return instance;
    }

    private void registerActivityListener(Application application) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
                @Override
                public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                    /**
                     *  監聽到 Activity創建事件 將該 Activity 加入list
                     */
                    activities.add(activity);
                }

                @Override
                public void onActivityStarted(Activity activity) {

                }

                @Override
                public void onActivityResumed(Activity activity) {

                }

                @Override
                public void onActivityPaused(Activity activity) {

                }

                @Override
                public void onActivityStopped(Activity activity) {

                }

                @Override
                public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

                }

                @Override
                public void onActivityDestroyed(Activity activity) {
                    if (null == activities && activities.isEmpty()) {
                        return;
                    }
                    if (activities.contains(activity)) {
                        /**
                         *  監聽到 Activity銷燬事件 將該Activity 從list中移除
                         */
                        activities.remove(activity);
                    }
                }
            });
        }
    }
}

 

 

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