Android疑难杂症之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没法像正常情况下一样,完成预期的初始化流程,从而为之后的运行,增加了很多不确定性。

  二、关于如何才能彻底关闭APP。可以看看Google内部人员是怎么说的以及大家在Stackoverflow上面的讨论……

  https://groups.google.com/forum/#!topic/android-developers/G_D3pKnGLt0  

  http://stackoverflow.com/questions/2033914/quitting-an-application-is-that-frowned-upon

  这里给大家截个图~ 

 

  所以,就单个应用来说,是没有现成的“可以自己关闭自己”的功能的……但是能做吗?当然可以做那就是捕获异常然后再清理掉所有的Activity再彻底关闭。这个网上都说要自己维护一个Activity序列,加个BaseActivity,然后在onCreate还有onDestroy的回调里面保存和移除……

  首先,确实要维护一个Activity的list,但是却没必要放在Activity里面做,完全可以放在application里面做。不知道大家有没有记得Application有个registerActivityLifecycleCallbacks的方法?我们只需要在Application做这个就可以了,如下图所示:

  

  然后,就可以了~以上所叙,同时还有一个偏方……

       个人理解:此偏方就是singleTask启动模式一样,跳转过去复用栈内任务,清空其上所有任务,这就变成了单任务栈了,前

提是这个ActivityNo1是在栈底,所以万变不离其宗,还是要栈内只有一个任务执行System.exit才能正确退出。

  以上所讲,浓缩在 https://github.com/wytings/CrashDemo

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值