进程的优先级与Low Memory Killer机制
Android 系统将尽量长时间地保持应用进程,但为了新建进程或运行更重要的进程,需要清除旧进程来回收内存。 为了确定保留或终止哪些进程,系统会对进程进行分类。 需要时,系统会首先消除重要性最低的进程,然后是清除重要性稍低一级的进程,依此类推,以回收系统资源。
系统出于体验和性能上的考虑,app在退到后台时系统并不会真正的kill掉这个进程,而是将其缓存起来。打开的应用越多,后台缓存的进程也越多。在系统内存不足的情况下,系统开始依据自身的一套进程回收机制来判断要kill掉哪些进程,以腾出内存来供给需要的app, 这套杀进程回收内存的机制就叫 Low Memory Killer。
通过命令行 cat /sys/module/lowmemorykiller/parameters/minfree查看最低内存阀值 ,
进程的优先级通过进程的adj值来反映,它是linux内核分配给每个系统进程的一个值,进程回收机制根据这个值来决定是否进行回收。adj的值越小,进程的优先级越高。
可以通过cat /proc/进程id/oom_adj可以看到当前进程的adj值。(需要[root]权限)
保活方法
1.Activity保活
监控手机锁屏解锁事件,在屏幕锁屏时启动1个像素透明的 Activity,在用户解锁时将 Activity 销毁掉。从而达到提高进程优先级的作用。
2.Service保活
前台进程是优先级最高的类型。在官方指南中有介绍:
创建一个前台服务用于提高app在按下home键之后的进程优先级
startForeground(ID,Notification):使Service成为前台Service。 前台服务需要在通知栏显示一条:
API level < 18 :参数2 设置 new Notification(),图标不会显示。
API level >= 18:在需要提优先级的service A启动一个InnerService。两个服务都startForeground,且绑定同样的 ID。Stop 掉InnerService ,通知栏图标被移除。
3.广播保活
在发生特定系统事件时,系统会发出广播,通过在 AndroidManifest 中静态注册对应的广播监听器,即可在发生响应事件时拉活。
但是从android 7.0开始,对广播进行了限制,而且在8.0更加严格https://developer.android.google.cn/about/versions/oreo/background.html#broadcasts
可静态注册广播列表:
https://developer.android.google.cn/guide/components/broadcast-exceptions.html
4.“全家桶”拉活
有多个app在用户设备上安装,只要开启其中一个就可以将其他的app也拉活。比如手机里装了手Q、QQ空间、兴趣部落等等,那么打开任意一个app后,其他的app也都会被唤醒。
5.系统Service机制拉活
START_STICKY:
“粘性”。如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。
START_NOT_STICKY:
“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。
START_REDELIVER_INTENT:
重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
START_STICKY_COMPATIBILITY:
START_STICKY的兼容版本,但不保证服务被kill后一定能重启。
只要 targetSdkVersion 不小于5,就默认是 START_STICKY。
但是某些ROM 系统不会拉活。并且经过测试,Service 第一次被异常杀死后很快被重启,第二次会比第一次慢,第三次又会比前一次慢,一旦在短时间内 Service 被杀死4-5次,则系统不再拉起。
6.账户同步 拉活
手机系统设置里会有“帐户”一项功能,任何第三方APP都可以通过此功能将数据在一定时间内同步到服务器中去。系统在将APP帐户同步时,会将未启动的APP进程拉活
7.JobScheduler 拉活
JobScheduler允许在特定状态与特定时间间隔周期执行任务。可以利用它的这个特点完成保活的功能,效果即开启一个定时器,与普通定时器不同的是其调度由系统完成。
同样在某些ROM可能并不能达到需要的效果(某米)
8.其他
推送拉活
根据终端不同,在小米手机(包括 MIUI)接入小米推送、华为手机接入华为推送。
Native拉活
Native fork子进程用于观察当前app主进程的存亡状态。对于5.0以上成功率极低。