Android如何让APP进程常驻内存?
如何让Android程序常驻内存,像QQ一样拥有强劲的生命力不被系统杀死?它传说中的进程保活(人类也在探索永生不死,App亦然),本文将会介绍进程保活的黑魔法,我想绝大部分开发者都会对它感兴趣。
进程保活的常见方案
黑色保活
何为黑色保活?就是利用不同App进程用广播相互唤醒。例如:
- 开机、网络切换、拍照、利用系统产生的广播唤醒app。
- 接入SDK,比如微信SDK会唤醒微信,支付宝SDK会唤醒支付宝。
- 假如你的手机安装了支付宝,淘宝等阿里系的app,那么你打开任意一个阿里系app后,就可以唤醒其他的阿里系app
目前Google已经意识到这些问题,所以在android N中取消了ACTION_NEW_PICTURE,CONNECTIVITY_ACTION等广播。
白色保活
这种进程保活方式非常简单,就是采用系统接口,启动前台Service,这样你会在通知栏看到一个Notification,让用户明确的感知到你在运行中。
灰色保活
这种保活手段目前应用非常广泛,它利用系统漏洞启动一个前台Service,与白色保活的区别在于,它不会在通知栏显示Notification,这样一来用户就无法察觉到运行着一个前台进程,但是你的进程优先级又是高于普通后台进程的。 目前很多app都采用灰色保活手段(微信,QQ),接下来我们一起来验证一下。以微信为例,首先打开微信,然后home键,确认通知栏无Notification,然后进入adb
shell执行如下shell命令: dumpsys
activity services com.tencent.mm
通过以上命令,打印出指定包名进程中的Service信息,你会看到isForeground=true的信息,但是通知栏却没有看到Notification。这就是进程保活的黑魔法。
代码实现
我将其命名位GohnsonSerivice(强生服务,正所谓人如其名),具有强大生命力的服务。
接下来你需要做的就是在Manifest中注册服务。以及在app中启动Service。这样一来你的Service就能实现灰色保活了
灰色保活并不代表你的Service能够永生,只能说明是提高了进程优先级。如果你的app进程占用了大量的系统资源,按照系统进程回收的策略,同样会kill你的app。为了进行对比,我加入了一个普通的Service进程
NormalService
进程回收策略
出于性能上的考虑,app在后台时系统并不会立即kill它,而是将其缓存起来。打开的应用越多,后台缓存的进程也越多。在系统资源不足的情况下,会根据进程回收机制来决定要kill掉哪些进程,以腾出资源来供给需要的app。这套策略就是Low Memory Killer ,它是基于Linux内核的 OOM Killer(Out-Of-Memory killer)机制诞生。
如何判断进程的优先级呢?
我们知道进程回收是依赖进程优先级进行的,那么如何判断进程的优先级高低呢?那就需要了解oom_adj:
它是linux内核分配每个进程的一个值,代表进程优先级,进程回收时就是依据它来决定是否回收。其值越大进程优先级越低,越容易被回收,并且普通的app进程oom_adj>=0,系统进程的oom_adj才可能<0
下面以Demo为例,查看其进程的oom_adj(注意以下测试结果中的oom_adj数值在不同设备上结果不一样)
ps
|grep com.vjson.gohnsonservice
- UI进程:com.vjson.gohnsonservice
- 灰色保活进程:com.vjson.gohnsonservice:gohnson
- 普通后台进程:com.vjson.gohnsonservice:normal
cat /proc/进程ID/oom_adj
从上图可以看到UI进程的oom_adj=0,保活进程oom_adj=2,普通后台进程oom_adj=8。然后按home键将app切到后台,在观察各个进程oom_adj的值变化。你会发现UI进程的值变大了。
以上测试结果可以看出,灰色保活服务进程的优先级明显高于普通后台服务进程,UI进程位于前台时优先级非常高,切到后台之后oom_adj明显增大(进程优先级明显降低)。由于UI进程占用的资源最多,系统资源不足时肯定优先杀掉这些资源咱用高的进程以腾出资源。所以为了尽量避免后台UI进程被杀,要尽可能的释放不用的资源。
总结
内存保活是一把双刃剑,用得好可以提升用户体验,用的不好那就是Android系统中的牛皮癣。
转载地址:http://blog.csdn.net/lihaoxiang123/article/details/62422434