何时发生

当我们的app被切到后台的时候,比如用户按下了home键或者切换到了别的应用,总之是我们的app不再和用户交互了,这个时候对于我们的app来说就是什么事情都可能发生的时候了,因为系统会认为你现在已经不是那么重要了,而和用户正在交互的app的优先级是最高的了,系统会想尽一切办法保证这些app的正常运行,如果这时这些app再申请更多的资源,如内存时,当目前的系统状况无法满足时,系统便会拿后台app开刀,也就是很粗鲁的杀掉整个app的进程,这时你也别指望onDestroy之类的callback会触发,你唯一能指望的就是在切后台的时候onPause、onStop和onSaveInstanceState之类的方法,如果你有状态需要保存那么应该在这些地方处理,不要寄希望于onDestroy,它会让你失望的,在这个地方用来释放资源还是ok的。由于系统要杀进程,那么紧接着的问题就是杀哪个进程,系统为此专门有个模块叫LML(low memory killer),详情可以参考下官方文档,见这里:processes-and-threads

再次切回app的行为

比如你在离开app的时候,已经打开了3个act,分别是A,B,C,C在最顶端,也就是任务栈顶,A是你的main activity,假设在后台期间被系统杀掉进程了,后面如果用户再次回来(通过recent tasks或者直接点击launcher里的app icon),这时展现在你眼前的将会是重建后的C activity,而不是正常情况下启动的A,系统同时也恢复了当初的任务栈,也就是说栈里的内容还是A,B,C,这时如果你按下了back键结束了C,那么系统又会帮我们重建B,A在B结束的时候也是一样的逻辑。这里需要注意一点就是,如果是用户自己杀掉了app,那么再次启动的时候回到的是A而不是C,只要记住是系统的错导致我们被杀的话,那么再次回到的话系统就有责任帮我们重建act。关于重建act的详情,可以参考官方文档recreating-activity。切回来之后虽然act是被重建了,但如果你代码里用了单例这样的东西来存一些变量的值,那么很不幸,这时所有单例中的字段全变成默认值了(0, false or null),因为你想啊,进程都被杀死了啊,所有静态字段等等都没了。stackoverflow有这样的问题,比如这个静态变量变成null了
目前笔者在维护的代码里有类似的构造,线上也确实出现了些类似的问题,着实蛋疼啊,准备改掉这种单例datakeeper的写法,思路大体有以下几种:

  1. 不改现有的单例datakeeper写法,但是增加永久存储支持,比如写到SP中,以后如果发现字段中没值了,那么就去SP中读一发;
  2. 数据通过Intent传递,这样也能保证不丢失,因为系统重建act的时候,用的Intent和当时启动act时的Intent是一样的,所以如果你所需要的数据都是以这种方式传递的,那恭喜你,you are safe,你要做的只是从Intent中解析出来你需要的数据;
  3. 在onSaveInstanceState中保存数据,在onCreate()/onRestoreInstanceState()中恢复数据;

如何模拟

由于系统后台杀进程具有一定的随机性,所以作为开发人员不可能去坐等这种情况发生,我们得有方法能很快速的复现,具体步骤如下:

                           模拟后台杀进程的步骤

参考 stackoverflow的提问

Android app被系统kill的场景的更多相关文章

  1. wemall doraemon中Android app商城系统工具集合类,包含各种程序中用到的静态方法

    wemall doraemon中Android app商城系统工具集合类,包含各种程序中用到的静态方法,可用于其他商城或者系统的编程参考 package cn.zzu.edu.wemall.utils ...

  2. 防止Android程序被系统kill掉的处理方法

    转载请注明出处:http://blog.csdn.net/cuiran/article/details/38851401 目前遇到一个问题程序需要一直运行,并显示在最前端,但是运行一段时间发现会被系统 ...

  3. Android APP使用系统签名

    Android M平台在写APP测试使用MediaRecoder通过AudioSource.VOICE_CALL来录制通话上下行音的时候,需要权限 <uses-permission androi ...

  4. Android app作为系统应用实现功能笔记

    1.禁用StatusBar相关功能需要添加权限 <uses-permission android:name="android.permission.STATUS_BAR"&g ...

  5. wemall doraemon中Android app商城系统解决左侧抽屉菜单和viewpager不能兼容问题

    完美解决左侧抽屉菜单和viewpager不能兼容左右滑动的问题,可进行参考. WeMall-Client/res/layout/wemall_main_ui.xml </RadioGroup&g ...

  6. wemall doraemon中Android app商城系统向指定URL发送GET方法的请求代码

    URL的openConnection()方法将返回一个URLConnection对象,该对象表示应用程序和 URL 之间的通信链接.程序可以通过URLConnection实例向该URL发送请求.读取U ...

  7. [系统集成] Android 自动构建系统

    一.简介 android app 自动构建服务器用于自动下载app代码.自动打包.发布,要建立这样的服务器,关键要解决以下几个问题: 1. android app 自动化打包android 的打包一般 ...

  8. 如何让自己的Android程序永不被系统kill

    一般来说,在Android系统中,当某进程较长时间不活动,或系统资源比较紧时,该进程可能被系统kill掉,以此来回收一些资源.Android系统会根据进程的优先级来选择性地杀死一些进程,优先级从高到低 ...

  9. 转Android APP安装后不在桌面显示图标的应用场景举例和实现方法

    转http://www.cnblogs.com/allenzheng/p/4510725.html#3186608 Android APP安装后不在桌面显示图标的应用场景举例和实现方法 最近在为公司做 ...

随机推荐

  1. 【类库】私房干货.Net数据层方法的封装

    [类库]私房干货.Net数据层方法的封装 作者:白宁超 时间:2016年3月5日22:51:47 摘要:继上篇<Oracle手边常用70则脚本知识汇总>文章的发表,引起很多朋友关注.便促使 ...

  2. nodejs 代理 解决开发环境跨域问题

    前后端分离项目中,会遇到跨域问题.解决方法无非就是jsonp cors等. 本次项目前端不搭node服务,线上用nginx搭站点,nginx转发ajax请求server. 本地开发环境的跨域问题用no ...

  3. POST方式提交表单时,后台接受实体如果继承了父类,将无法映射表单对应数据

    引言 刚才在做一个post提交表单时,我在表单里放了几个隐藏域用来存放数据,表单name属性和后台实体属性签名保持一致.只是后台Action参数包含继承关系,所以无法获取到表单对应的值.刚开始一直纳闷 ...

  4. JAVA安全模型

    作为一种诞生于互联网兴起时代的语言,Java 从一开始就带有安全上的考虑,如何保证通过互联网下载到本地的 Java 程序是安全的,如何对 Java 程序访问本地资源权限进行有限授权,这些安全角度的考虑 ...

  5. mysql null值处理详细说明

    在讲null之前,我们先看一个例子 表数据如下: 3306>select * from t1; +------+-------+ | id | name | +------+-------+ | ...

  6. 获取documents、tmp、app、Library的路径的方法

    phone沙箱模型的有四个文件夹: documents,tmp,app,Library 1.Documents      您应该将所有的应用程序数据文件写入到这个目录下.这个目录用于存储用户数据或其它 ...

  7. 【C#】DataRowState演变备忘

    环境:.net 2.0 DataRow的行状态一段时间不用就会吃不准,记录一下,备查. DataRowState 演变表 行属于如下状态时进行右边操作→ 后的状态演变 添加到表 dt.Rows.Add ...

  8. Xamarin Studio在Mac环境下的配置和Xamarin.iOS常用控件的示例

    看过好多帖子都是Win环境装XS,Mac只是个模拟器,讲解在Mac环境下如何配置Xamarin Studio很少,也是一点点找资料,东拼西凑才把Xamarin Studio装在Mac上跑起来,如下: ...

  9. c#动态加载卸载DLL的方法

    这篇文章介绍了c#动态加载卸载DLL的方法,有需要的朋友可以参考一下 c#中通过反射可以方便的动态加载dll程序集,但是如果你需要对dll进行更新,却发现.net类库没有提供卸载dll程序集的方法.在 ...

  10. Eclipse切换SVN用户

    1. 点击windows --> preference --> Team --> SVN,查看当前的SVN接口. 2. 如果SVN接口是JavaHL,那么找到C:\Documents ...