應用有時會突然得崩潰,這樣會比較影響用戶體驗。如果想要崩潰后重啟應用呢。Java中有個UncaughtExceptionHandler的接口, 通過實現此接口,能夠處理線程被一個無法捕捉的異常所終止的情況。如上所述的情況,handler將會報告線程終止和不明原因異常這個情況,如果沒有自定義handler,線程管理組就被默認為報告異常的handler。
那么創建一個類實現UncaughtExceptionHandler,重寫
uncaughtException()方法,當異常發生時會轉入該函數來處理。
@Override
public void uncaughtException(Thread thread, Throwable ex) {
if (!handleException(ex) && mDefaultHandler != null) {
// 如果用戶沒有處理則讓系統默認的異常處理器來處理
mDefaultHandler.uncaughtException(thread, ex);
} else {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Log.e(TAG, "error : ", e);
}
if (mIsRestartApp) { // 如果需要重啟
Intent intent = new Intent(mContext.getApplicationContext(), mRestartActivity);
AlarmManager mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
//重啟應用,得使用PendingIntent
PendingIntent restartIntent = PendingIntent.getActivity(
mContext.getApplicationContext(), 0, intent,
Intent.FLAG_ACTIVITY_NEW_TASK);
mAlarmManager.set(AlarmManager.RTC, System.currentTimeMillis() + mRestartTime,
restartIntent); // 重啟應用
}
// 結束應用
((CrashApplication) mContext.getApplicationContext()).removeAllActivity();
}
}
/**
* @param context 上下文
* @param isDebug 是否是Debug模式
* @param isRestartApp 是否支持重啟APP
* @param restartTime 延遲重啟時間
* @param restartActivity 重啟后跳轉的 Activity,建議是SplashActivity
*/
public void init(Context context, boolean isDebug, boolean isRestartApp, long restartTime,Class restartActivity) {
mIsRestartApp = isRestartApp;
mRestartTime = restartTime;
mRestartActivity = restartActivity;
init(context, isDebug);
}
public void init(Context context, boolean isDebug) {
mTips = "很抱歉,程序出現異常,即將退出...";
mIsDebug = isDebug;
mContext = context;
// 獲取系統默認的 UncaughtException 處理器
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
// 設置該 CrashHandler 為程序的默認處理器
Thread.setDefaultUncaughtExceptionHandler(this);
}
需要應用的application繼承CrashApplication
public class CrashApplication extends Application {
private List<Activity> mActivityList;
@Override
public void onCreate() {
super.onCreate();
mActivityList = new ArrayList<>();
}
/**
* 添加單個Activity
*/
public void addActivity(Activity activity) {
// 為了避免重復添加,需要判斷當前集合是否滿足不存在該Activity
if (!mActivityList.contains(activity)) {
mActivityList.add(activity); // 把當前Activity添加到集合中
}
}
/**
* 銷毀單個Activity
*/
public void removeActivity(Activity activity) {
// 判斷當前集合是否存在該Activity
if (mActivityList.contains(activity)) {
mActivityList.remove(activity); // 從集合中移除
if (activity != null){
activity.finish(); // 銷毀當前Activity
}
}
}
/**
* 銷毀所有的Activity
*/
public void removeAllActivity() {
// 通過循環,把集合中的所有Activity銷毀
for (Activity activity : mActivityList) {
if (activity != null){
activity.finish();
}
}
//殺死該應用進程
android.os.Process.killProcess(android.os.Process.myPid());
}
}
在application中初始化
UncaughtExceptionHandlerImpl.getInstance().init(this, BuildConfig.DEBUG, true, 0, MainActivity.class);
并在MainActivity初始化方法中將當前對象添加到application中
((App) getApplication()).addActivity(this);
當然,在uncaughtException()方法中,也可以收集手機信息的一些操作,記得獲取權限就可以了。