以下所讲,浓缩在 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. 文件上传实现ajax假异步

    $.ajaxFileUpload({ url : getSitePath()+'/jlyElderly/doUpdateImage', secureuri : false,//是否需要安全协议 fil ...

  2. 根据日期查询年龄js

    function ages(str) { var r = str.match(/^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2})$/); if(r==null)return f ...

  3. 调用微信JS-SDK接口上传图片

    最近要在微信上做个问卷调查,有个上传图片功能,折腾找了半天资料,都不好弄,最终打算调用微信提供的上传图片接口,实现上传图片功能!此功能最大的好处是可以在微信服务器上暂存图片,减少本地服务器图片的缓存, ...

  4. jQuery使用blur()方法触发两次的解决方法

    在项目中的textarea在是去焦点时对文本内容进行验证,这时候使用了blur方法,但是实现时blur的回调函数执行了两次,这里我也不知道为什么,然后就尝试先解除blur事件绑定,然后再绑定blur事 ...

  5. mysql设置服务器编码

    今天写java程序的时候出现了插入mysql数据中文乱码问题,确定数据库和表的编码都已指定utf-8.百度后得知mysql安装后需设置服务器编码,以下是解决方法(ubuntu; mysql 5.6.2 ...

  6. Restful Framework (二)

    目录 一.认证 二.权限 三.限制访问频率 四.总结 一.认证(补充的一个点) 回到顶部 认证请求头 #!/usr/bin/env python # -*- coding:utf-8 -*- from ...

  7. C语言实现二叉排序树

    程序以'#'结尾的二叉排序树. /*(双重指针 BSTree *T)问:数据结构中 二叉树建立结点为什么用 双重指针?详细解释下双重指针 答:指针的指针.因为树的结点要用指针描述.如果只用指针,作形参 ...

  8. memcached安装+绑定访问ip

    安装: 1.由于memcached是基于libevent的,需要安装libevent,libevent-devel $yum -y install libevent libevent-devel 2. ...

  9. Centos7使用squid实现正向代理

    正向代理:代理服务器帮助客户端(浏览器)实现互联网的访问 (1)代理服务器配置 1.安装squid yum install squid -y 2.编辑squid配置文件 #vim /etc/squid ...

  10. 如何通过 Redis 实现分布式锁

    分布式锁需要解决的问题: 互斥性:任意时刻只能有一个客户端获取锁 安全性:锁只能被持有该锁的客户端删除 死锁:获取锁的客户端因为意外宕机未能释放锁,其他客户端再也无法获取到该锁导致死锁 容错:宕机后客 ...