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

  首先就这个名字来说,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做这个就可以了,如下图所示:

  

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

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

Android疑难杂症之KillProcess 和System.exit 无效的更多相关文章

  1. android Process.killProcess 和 System.exit(0) 区别

    1 Process.killProcess  和 System.exit(0) 两个都会 kill 掉当前进程. 你可以打开 DDMS 查看进程号,或 adb shell 进入 shell 然后 ps ...

  2. Android 与Java 进程退出 killProcess与System.exit

    android所有activity都在主进程中,在清单文件Androidmanifest.xml中可以设置启动不同进程,Service需要指定运行在单独进程?主进程中的主线程?还是主进程中的其他线程? ...

  3. [Android疑难杂症]动态改变Background后Padding无效的问题

    前言 在Layout中指定好background和padding以后,程序里面动态修改background之后padding就失效了,貌似是一个BUG,这里找到了一篇英文文章,简单翻译分享一下. 声明 ...

  4. android开发两种退出程序方式(killProcess,System.exit)

    KillProcess: 在android中我们如果想要程序的进程结束可以这样写: android.os.Process.killProcess(android.os.Process.myPid()) ...

  5. android Activity类中的finish()、onDestory()和System.exit(0) 三者的区别

    android Activity类中的finish().onDestory()和System.exit(0) 三者的区别 Activity.finish() Call this when your a ...

  6. android开发时,finish()跟System.exit(0)的区别

      这两天在弄Android,遇到一个问题:所开发的小游戏中有背景音乐,玩的过程中始终有音乐在放着,然后在我退出游戏后,音乐还在播放! 我看了一下我最开始写的退出游戏的代码,就是简单的finish() ...

  7. android finish和system.exit(0)的区别

    finish是Activity的类,仅仅针对Activity,当调用finish()时,只是将活动推向后台,并没有立即释放内存,活动的资源并没有被清理:当调用System.exit(0)时,杀死了整个 ...

  8. 【Android】System.exit(0) 退出程序

    许多 Android 应用程序都是连续点击两下返回键时退出程序,代码如下: private long exitTime = 0; @Override public boolean onKeyDown( ...

  9. How to use Android Activity's finish(), onDestory() and System.exit(0) methods

    Activity.finish() Calling this method will let the system know that the programmer wants the current ...

随机推荐

  1. [How to]Cloudera manager 离线安装手册

    2016-01-1910:54:05  增加kafka 1.简介 本文介绍在离线环境下安装Cloudera manager和简单使用方法 2.环境 OS:CentOS 6.7 Cloudera man ...

  2. [How to] 使用Xib来创建view

    1.简介 代码库 正如之前博客介绍的,xib可定义页面的某个部分,特别当此部分区域的view集中并且还有一些相互关联性(如隐藏等)是i特别适合使用xib来进行封装. 本文为[How to]使用自定义c ...

  3. docker基于本地模版导入创建镜像

    /* 因为直接去网站拿会下载的慢,所以直接到网站里,对着此包--〉右键--〉复制链接地址 网站地址:https://openvz.org/Download/template/precreated */ ...

  4. google fcm 推送的流程

    总结:1.给一个人推,能成功,2.给多个人推,有两种,一种是给组推,一种是给主题推,之前用的是组推,但是不成功,这里换成主题推: <?phpnamespace App\Http\Controll ...

  5. 百度之星资格赛--IP聚合

    IP聚合 Accepts: 1901 Submissions: 4979 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/6553 ...

  6. sizeof(类)

    类的大小是什么?确切的说,类只是一个类型定义,它是没有大小可言的. 用sizeof运算符对一个类型名操作,得到的是具有该类型实体的大小.首先:我们要知道什么是类的实例化,所谓类的实例化就是在内存中分配 ...

  7. jquery键盘常见事件

    一.在看jquery的时候有几个常见的键盘事件,我写在这里: 1.keydown() keydown事件会在键盘按下时触发. 2.keyup() keyup事件会在按键释放时触发,也就是你按下键盘起来 ...

  8. 【剑指offer】面试题 64. 求 1+2+3+...+n

    面试题 64. 求 1+2+3+...+n 题目:求1+2+3+...+n,要求不能使用乘除法.for.while.if.else.switch.case等关键字及条件判断语句(A?B:C). 1.采 ...

  9. php过滤表单输入的emoji表情

    1.过滤emoji表情的原因 在我们的项目开发中,emoji表情是个麻烦的东西,即使我们可以能存储,也不一定能完美显示,因为它的更新速度很快:在iOS以外的平台上,例如PC或者android.如果你需 ...

  10. JS中事件绑定问题

    今天编写代码时遇到一个问题,我的判断语句(IFLESE)老是顺序执行结束后又跳到中间的语句里去执行了,找了半天没发现问题,最后才发现是事件绑定闹得鬼,不多说,先上代码为敬. JSP里 <butt ...