团队原创分享:Android版后台保活实战分享(进程
保活篇)
哪些部分需要“保活”?
按照我们的理解包含两部分:
1. ⽹络连接保活:
如何保证消息接收实时性。详见本⽂上篇《》
2. 进程保活:
尽量保证应⽤的进程不被Android系统回收。这是本⽂要讨论的内容。
进程保活概述
在Android系统⾥,进程被杀的原因通常为以下⼏个⽅⾯:
中级会计职称
原因a可以单独作为⼀个课题研究。原因c、d⽬前在上没有特殊处理。这⾥讨论的就是如何应对Android Low Memory Killer。
进程保活实施:进程拆分
上图表述的是主要的⼏个进程:
如何向银行申请贷款
拆分⽹络进程,确实就是为了减少进程回收带来的⽹络断开。
可以看到push的内存要远远⼩于worker。⽽且push的⼯作性质稳定,内存增长会⾮常少。这样就可以保证,尽量的减少push 被杀的可能。这⾥有个思路,但限制⽐较多,也抛砖引⽟。启动⼀个纯C/C++ 的进程,没有Java run time ,内存使⽤极低。
手机银行怎么转账
这种做法限制很明显,如:没有Java run time ,所以⽆法使⽤Android系统接⼝。缺乏权限,也⽆法使⽤各种shell命令操作(如am)。但可以考虑⼀下⽤途:⾼强度运算,⽹络连接,⼼跳维持等。⽐如Shadowsocks-android就如此,通过纯c命令⾏进程,维护着socks5代理 (Android M运⾏正常)。
tools进程的拆分也同样是内存的原因:
在进⼊后台后,会主动把tools进程kill掉。
进程保活实施:及时拉起
系统回收不可避免,及时重新拉起的⼿段主要依赖系统特性。从上图看到, push有AlarmReceiver, ConnectReceiver,BootReceiver。这些receiver 都可以在push被杀后,重新拉起。特别AlarmReceiver ,结合⼼跳逻辑,被杀后,重新拉起最多⼀个⼼跳周期。
⽽对于worker,除了⽤户UI操作启动。在接收消息,或者⽹络切换等事件, push也会通过LocalBroadcast,重新拉起worker。这种拉起的worker ,⼤部分初始化已经完成,也能⼤⼤提⾼⽤户点击的启动速度。
历史原因,我们在push和worker通信使⽤Broadcast和AIDL。实际上,我⼀直不喜欢这⾥的实现,AIDL代码冗余多, broadcast效率低。欢迎⼤家分享更好的思路或者⽅法。
进程保活实施:进程优先级
Low Memory Killer 决定是否杀进程除了内存⼤⼩,还有进程优先级:
公司注册成立流程上表的数字可能在不同系统会有⼀定的出⼊,但明确的是,数值越⼩,优先级越⾼。对于优先级相同的进程,总是会把内存占⽤多的先kill。提⾼进程优先级是保活的最好⼿段。
正常情况下的oom_adj:
⽽被提⾼优先级后:
从统计上报看,提⾼后的效果极佳。原理:Android 的前台service机制。但该机制的缺陷是通知栏保留了图标。
对于 API level < 18 :调⽤startForeground(ID, new Notification()),发送空的Notification ,图标则不会显⽰。对于 API level >= 18:在需要提优先级的service A启动⼀个InnerService,两个服务同时startForeground,且绑定同样的 ID。Stop 掉InnerService ,这样通知栏图标即被移除。
这⽅案实际利⽤了Android前台service的漏洞。在评估了国内不少app已经使⽤后,才进⾏了部署。其实⽬标是让⼤家站同⼀起跑线上,哪天google 把漏洞堵了,效果也是⼀样的。
QA环节
Q:之前看的架构分享,貌似是通过单⼀Activity,⽤多个Fragment切换来实现的多窗⼝。如果分进程的话,看起来Gallery和
动物学校
WebView是单独的⼀个Activity,我的理解是否正确呢?以及进⼊后台之后,为何只kill tools⽽不⼀起释放work呢?
A:Fragment的改造只是⽤在有限的⼏个UI上,⼤部分的UI,对于切换时间要求不⾼,还是保留成activity,Gallery和WebView都是单独的activity,所以才可能另外⼀个进程的。对于我们来说worker的保活仅次于⽹络的push,worker如果频繁被杀,⽤户每次启动都需要
等待,这个就不好了。所以,我们在后台,只会kill tools,不会主动kill worker。
Q:除了提⾼进程的优先级,在内存⽅⾯有什么处理或优化的技术吗?
A:不可否认,其实是内存⼤户了,现阶段我们主要关注内存泄漏,没有专门去减少内存的使⽤,毕竟内存意味着cache,意味着⽤户体验更快,后续对于内存优化我们有⼀些规划,⽐如说,在cache这块照顾⼀些低端机。
Q:我记得很久以前听说过使⽤⼀个像素的浮动窗⼝来保活,不知道现在还有没有呢?
A:我们有想过,也听说过有其他app是这样做的,但从来没实现过这个⽅案。
Q:你们push进程与worker进程采⽤过socket通信⽅案么?采⽤的话效果怎么样?
A:有考虑过⽤socket,后续也可能会有这种尝试,但因为push和worker依赖代码太多,伤筋动⾻了,但估计也要⽐AIDL好,AIDL对于应⽤出问题后能做的事情太少了。
>生日祝福短信