发表于: 2019-01-03 19:49:46
0 815
今天完成的事情
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
评论