Low Memory Killer
打开的应用越多,后台缓存的进程也越多。因为系统出于体验和性能上的考虑,app在退到后台时系统并不会真正的kill掉这个进程,而是将其缓存起来。于是在系统内存不足的情况下,系统开始依据自身的一套进程回收机制来判断要kill掉哪些进程,以腾出内存来供给需要的app, 这套杀进程回收内存的机制就叫 Low Memory Killer。
进程的优先级(by:https://developer.android.google.cn/guide/components/activities/process-lifecycle?hl=zh-cn)
前台进程
用户正在使用的程序,一般系统是不会杀死前台进程的,除非用户强制停止应用或者系统内存不足等极端情况会杀死。
可见进程
用户正在使用,看得到,但是摸不着,没有覆盖到整个屏幕,只有屏幕的一部分可见进程不包含任何前台组件,一般系统也是不会杀死可见进程的,除非要在资源吃紧的情况下,要保持某个或多个前台进程存活施。
服务进程
在内存不足以维持所有前台进程和可见进程同时运行的情况下,服务进程会被杀死。
后台进程
系统可能随时终止它们,回收内存。
空进程
某个进程不包含任何活跃的组件时该进程就会被置为空进程,完全没用,杀了它只有好处没坏处,第一个干它。
内存阈值
内存阈值在不同的手机上不一样,一旦低于该值,Android便会杀死对应优先级的进程。一旦低于该值,Android便开始按逆序关闭进程。即优先级从最高的空进程开始,逆序关闭,直到内存足够。
如何判断进程的优先级?
通过oom_adj 值,判断进程的优先级,不同手机的oom_adj 值可能不一样。
我们了解这个有什么用呢?PS:了解这个你才能想办法保证自己怎么不被杀掉。
网上的一些方案和自己认为有用的方案
1 开启一个像素Activity(伪前台进程)
在锁屏的时候在本进程开启一个Activity,为了欺骗用户,让这个Activity的大小是1像素,并且透明无切换动画,在开屏幕的时候,把这个Activity关闭掉,所以这个就需要监听系统锁屏广播。
我们的应用就始终和前台进程是一样的优先级了,为了省电,系统检测到锁屏事件后一段时间内会杀死后台进程,如果采取这种方案,就可以避免了这个问题,但是还是有被杀掉的可能。
Android5.0以下:
Process.killProcessQuiet(pid);
Android5.0以后:
Process.killProcessQuiet(app.pid);
Process.killProcessGroup(app.info.uid, app.pid);
应用退出后,ActivityManagerService不仅把主进程给杀死,另外把主进程所属的进程组一并杀死,这样一来,由于子进程和主进程在同一进程组,子进程在做的事情,也就停止了。
2 相互唤醒(广播唤醒)
相互唤醒的意思就是,假如你手机里装了支付宝、淘宝、天猫、UC等阿里系的app,那么你打开任意一个阿里系的app后,有可能就顺便把其他阿里系的app给唤醒了。这个完全有可能的。此外,开机,网络切换、拍照、拍视频时候,利用系统产生的广播也能唤醒app,不过Android N已经将这三种广播取消了。
3 JobSheduler机制保活(不推荐)
JobSheduler是作为进程死后复活的一种手段,native进程方式最大缺点是费电, Native 进程费电的原因是感知主进程是否存活有两种实现方式,在 Native 进程中通过死循环或定时器,判断主进程是否存活,当主进程不存活时进行拉活。其次5.0以上系统不支持。 但是JobSheduler可以替代在Android5.0以上native进程方式,这种方式即使用户强制关闭,部分厂商手机(如:华为)也能被拉起来,但AndroidN失效。
4 粘性服务&与系统服务捆绑()
这个是系统自带的,onStartCommand方法必须具有一个整形的返回值,这个整形的返回值用来告诉系统在服务启动完毕后。Service的onStartCommand方法里返回 STATR_STICK,onDestory中start自启(准确的将算不上进程拉活,只能算service自启,force_stop后不能正常拉活)。
5 监听第三方app开放的静态广播(同2)
需要大量反编译app去找开放的静态广播,而且不保证长期有效,可能第三方开放广播在版本升级时改为私有广播,如果自己公司有多个app,可广播互相拉起。
6 NDK+Socket通过fork实现进程保活方案()
实现进程守护实际是守护app的主要服务,当app主进程被系统kill时,主要服务也会杀死,守护进程将其唤醒。
实现原理图:
进程保活方案调研结果
未能实现真正意义上的进程保活。
光从保活这一点来说,绑定一个像素activity和循环一个无声的声音这种方法比较好,但是对用户来说太流氓了,不推荐。 对于有硬性需求的,可以引导用户加入白名单。至于推送, 可以尝试集成多个推送方案,小米,华为等都有推送sdk,在对应手机上可以确保收到消息, 然后像百度这种是多app公用通道的,也就是手机中有一个使用百度推送的app被允许后台启动,就能让其他app收到推送。随着Android版本的不断更新及国内厂商对ROM的不断优化,如何最大可能的对进程保活,是Android一道需要长期学习/钻研的学问,也是Android开发者不得不面对的问题。
引援:https://www.jianshu.com/p/1c353edf73ba