发表于: 2019-01-03 19:49:46

0 659


今天完成的事情

KillProcess 和System.exit

从命名上来看,kill了process 或者 system.exit确实已经把APP杀掉了,特别是当你栈里只有一个Activity的时候,这个措施是行之有效的。但是因为Android framework的原因,在一些情况下APP会被重启,其实更准确地来说是App被恢复了。什么情况呢?就是如果你还有未被主动关闭的Activity的时候。比如ActivityA -打开-> ActivityB —打开—ActivityC,然后再ActivityC进行system.exit或者Process.killProcess(Process.myPid);此时因为在C导致整个APP被关闭了,而A和B却什么也没操作就被关了,framework 层认为这是被冤杀的,所以即便是我们自己选择去kill的,就当前的Framework 的机制来说,它认为这种主动的退出方式是一种异常退出……,所以它会竭尽全力去恢复这个APP。

在“异常退出”的情况下,Framework会保存APP的一些状态信息比如Activity运行栈,然后恢复一个Android应用程序时,会先从栈里面移除异常的Activity,相当于Back键操作。如果移除后没有Activity则不恢复也就是“关闭成功的假象”,如果还有Activity则会恢复移除后的第一个Activity。

来我们继续以上面的A->B->C 打开的顺序来进行说明:

1、如果在ActivityC kill则,APP恢复时会显示ActivityB;

2、如果在ActivityB kill Process则会恢复ActivityA;

3、如果在ActivityA kill Process,由于没有上一个Activity,则程序恢复失败,也就是保持dead状态。

由于App恢复的时候,只有一个Activity,但它又保留了之前Activity栈的信息,那如何处理Back键呢?我们以上面的第一种情况来看,恢复了ActivityB,但是ActivityB上面还有一个ActivityA,所以恢复了ActivityB后,我们点Back键时,会打开ActivityA,虽然Framework本来也是想resume ActivityA,但是无奈它已经死了,所以只能重新再create一次。同理,可一直往back,直到所有的Activity都没了。

基础信息铺垫完了,我们现在开始针对性的说明两个问题:1、这种异常的程序恢复会有什么缺陷?2、那到底如何彻底关闭APP?

一、我们先来说说缺陷,首先,如果是只有一个Activity,关了就关了好像也没什么大事,毕竟出了异常。但是如果是有多个Activity的话,恢复后就很有可能出问题。为什么?因为我们知道恢复的只有一个Activity,如果你的各种初始化参数不是在Application里面做而是在某个加载页做的话,那么恢复这个Activity极有可能会因为调用了些没有初始化过的类再次报错而崩溃,这种情况也会出现在按Back键的时候,然后再继续恢复一次,印象中有三次机会,三次还救不了,Framework就会说:算了,就这样吧……

所以,这种异常恢复最大的缺陷就是APP没法像正常情况下一样,完成预期的初始化流程,从而为之后的运行,增加了很多不确定性。

那么如何自己实现一个关闭应用的功能?

思路是维护一个Activity列表和BaseActivity,继承自BaseActivity的活动在创建时会被添加至列表,在销毁时会被移出列表,当需要退出应用时结束列表中的所有活动。

/*
用于管理所有活动
提供一系列管理活动的方法
*/
public class ActivityManager {

private static ActivityManager instance;

   //单例模式
   public static ActivityManager getInstance() {
       if (null == instance) {
           instance = new ActivityManager();
       }
       return instance;
   }

   //创建List用于暂存活动
private List<Activity> activityList = new ArrayList<>();

//方法:将活动添加到List
public void addActivity(Activity activity) {
       activityList.add(activity);
   }

   //方法:将活动从List中移除
   public void removeActivity(Activity activity) {
       activityList.remove(activity);
   }

   //方法:结束所有活动
public void finishAll() {
       for (Activity activity : activityList) {
           if (!activity.isFinishing()) {
               activity.finish();
           }
       }
       activityList.clear();
   }

   //结束除指定活动外的所有活动
public void finishAllElse(Activity specifiedActivity) {
       for (Activity activity : activityList) {
           if (activity != specifiedActivity && !activity.isFinishing()) {
               activity.finish();
           }
       }
   }
}


public class BaseActivity extends AppCompatActivity implements BaseView {

   @Override
   protected void onCreate(Bundle saveInstanceState) {
       super.onCreate(saveInstanceState);
       //活动被创建时会被添加到list中统一管理
    ActivityManager.getInstance().addActivity(this);
   }

   @Override
 protected void onDestroy() {
                 //当活动被销毁时会从list中被移除
    ActivityManager.getInstance().removeActivity(this);
         super.onDestroy();  
   }

}

收获

KillProcess 和System.exit



返回列表 返回列表
评论

    分享到