说在前面:
一开始有这个需求的时候,上网查了很多文章,最终我选定了http://blog.sina.com.cn/s/blog_ac843e330102vek5.html作为参考,但是这个方法虽然能够保证重启成功,但是在重启的速度上并不能达到我的预期,使用AlarmManager定时任务来启动总是会有莫名其妙的延迟(1~3秒左右,最长甚至有过5秒),所以在这个基础上作了一点小小的修改
开始介绍:
简单粗暴,线上源码:
import android.app.ActivityManager; import android.content.Context; import android.content.Intent; import myapplication.szm.com.myapplication.MyApplication; /** * Created by:Sun ZhongMou on 2017/9/8 16:42 **/ public class ReStartExceptionHandler implements Thread.UncaughtExceptionHandler { public static final String TAG = "ReStartExceptionHandler"; private static ReStartExceptionHandler mReStartExceptionHandler; private Thread.UncaughtExceptionHandler mDefaultHandler; private MyApplication mAppContext; public static ReStartExceptionHandler getInstance(){ if (mReStartExceptionHandler == null) { mReStartExceptionHandler = new ReStartExceptionHandler(); } return mReStartExceptionHandler; } public void initReStartExceptionHandler(MyApplication application){ //获取系统默认的UncaughtException处理器 mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); Thread.setDefaultUncaughtExceptionHandler(this); mAppContext = application; } @Override public void uncaughtException(Thread thread, Throwable ex) { if(!handleException(ex) && mDefaultHandler != null){ //如果用户没有处理则让系统默认的异常处理器来处理 mDefaultHandler.uncaughtException(thread, ex); }else{ Intent intent = mAppContext.getPackageManager().getLaunchIntentForPackage(mAppContext.getPackageName()); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); mAppContext.startActivity(intent); MyApplication.finishActivity(); } } /** * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成. * * @param ex * @return true:如果处理了该异常信息;否则返回false. */ private boolean handleException(Throwable ex) { if (ex == null) { return false; }Toast.makeText(mAppContext, "很抱歉,程序异常,即将退出!", Toast.LENGTH_LONG).show();return true; } }
自定义的异常捕捉器,通过
Intent intent = mAppContext.getPackageManager().getLaunchIntentForPackage(mAppContext.getPackageName()); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); mAppContext.startActivity(intent);
重启应用,而非通过
Intent intent = new Intent(application.getApplicationContext(), MainActivity.class);
另外,这里需要用到自定义的Application,代码如下:
import android.app.Activity; import android.app.Application; import com.facebook.drawee.backends.pipeline.Fresco; import java.util.ArrayList; import myapplication.szm.com.utils.ReStartExceptionHandler; /** * Created by Administrator on 2017/8/24. */ public class MyApplication extends Application { private static ArrayList<Activity> list = new ArrayList<>(); @Override public void onCreate() { super.onCreate(); Fresco.initialize(this); ReStartExceptionHandler.getInstance().initReStartExceptionHandler(this); } /** * Activity关闭时,删除Activity列表中的Activity对象*/ public static void removeActivity(Activity a){ list.remove(a); } /** * 向Activity列表中添加Activity对象*/ public static void addActivity(Activity a){ list.add(a); } /** * 关闭Activity列表中的所有Activity*/ public static void finishActivity(){ for (Activity activity : list) { if (null != activity) { activity.finish(); } } //杀死该应用进程 android.os.Process.killProcess(android.os.Process.myPid()); } }
其中
ReStartExceptionHandler.getInstance().initReStartExceptionHandler(this);用于初始化自定义异常捕捉器
另外有三个自定义方法addActivity,removeActivity以及finishActivity
这三个方法中前两者在应用的每一个Activity中都要调用,addActivity在onCreate()中调用,removeActivity在onDestory()中调用,finishActivity则是用来退出应用
PS:当然,你可以定义一个Activity的基类(如BaseActivity),在其中调用addActivity和removeActivity,然后所有Activity都继承他
使用这个异常捕捉器,你的应用在出现异常退出后会在极短时间内重新启动(0.5秒以内)
finishActivity则是用来退出应用