android app崩潰後自動重啟
阿新 • • 發佈:2018-12-31
1.偶然發現專案因為一場崩潰後,自動重啟到上一介面。因為未知原因,重啟後fragment顯示有誤,需要殺死程序後才能正常適應app。悲劇的是,因為馬上就重啟程序
了,導致LOG中看不到異常原因。非常不好除錯。
2.經過查資料得知,這些都是google的一種策略,當app崩潰後,會自動根據棧裡面的activity的順序,重啟棧頂activity。
3.有的手機保留了這個功能,有的手機估計是定製的原因,會遮蔽掉這個功能,導致以前我沒有注意這個現象。
4.避免無故重啟帶來的bug,讓app崩潰後自動關閉。
1)、首先在在application 自定義異常處理類。
// 以下用來捕獲程式崩潰異常 Thread.setDefaultUncaughtExceptionHandler(restartHandler); // 程式崩潰時觸發執行緒 registerActivityListener();//activity管理類
2)、在自定義的處理類中關閉棧中的activity,然後殺死當前app程序。此處result 是崩潰異常的資訊。
3)、activty管理,一般方法是在activity的基類中,在oncreate中 把activity新增到list陣列中,再在ondestry中刪除remove這個activity。public Thread.UncaughtExceptionHandler restartHandler = new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException(Thread thread, Throwable ex) { //下面為除錯用的程式碼,釋出時可註釋 Writer info = new StringWriter(); PrintWriter printWriter = new PrintWriter(info); ex.printStackTrace(printWriter); Throwable cause = ex.getCause(); while (cause != null) { cause.printStackTrace(printWriter); cause = cause.getCause(); } printWriter.flush(); printWriter.close(); String result = info.toString(); Log.i("sss",result); for (int i=0;i<activities.size();i++){ Log.i("sss",activities.get(i).getLocalClassName()); if (activities.get(i)!=null) activities.get(i).finish(); } android.os.Process.killProcess(android.os.Process.myPid()); } };
此處採用atcivity生命回撥監聽方法,在android14版本以上有效。
每個activity,從建立到銷燬都會回撥這個方法,可以避免有的activity不繼承基類等。private void registerActivityListener() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { registerActivityLifecycleCallbacks(new 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); } } }); } }