在某些手机或者平板上,android程序崩溃后,系统会根据堆栈信息强行把应用重新拉起。但是这种强行重启应用,会一些数据缺失的问题,造成二次崩溃,这样的体验是十分不好的。
所以我的目标就是崩溃后不要重新拉起应用。
如何解决崩溃后重新的问题,可以参见下面的文章,本文不做过多的描述,清空activityStack即可。
核心代码如下:
public class BuglyCrashHandler implements Thread.UncaughtExceptionHandler {
List 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 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 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);
}
}
});
}
}
}