前言Android进程和Service的保活是困扰Android开发者的一大难题。由于涉及到省电和内存管理策略,各厂商根据自己的理解,在发布自己的ROOM时,都会对标准的Android发布版本进行或多或少的改动,使得应用层程序在处理的过程中发生变化,并保持服务还活着。兼容是极其复杂和困难的,因为可能哪个手机或者哪个版本的省电策略改变了,那么保活流程和服务就会有差异。在应用场景中,即时通信应用(包括IM聊天应用、消息推送服务等)必须实现进程或服务保活,以保证消息的全时、实时传递。对于这个看似不起眼的问题,由于众多安卓手机和安卓系统版本的差异,实际处理起来充满了不确定性。本文根据笔者的实践和相关资料的整理,总结了自己对Android进程和Service保活的理解,希望能给大家的应用开发带来启发。概述最近做了一个Android项目,涉及到后台进程和Service的保活问题。在网上找了很多资料,基本的保活方法都测试过了。结果是:不同的手机,不同的安卓版本,保活效果不同。最难绕过的是厂商对“后台程序保活”的管理。本文主要总结了相应的实际效果和保活方法。但由于笔者能拿到的真机测试机数量有限,可能会有不完整的地方。请及时指正和补充,大家共同进步。手Q、微信等大型IM如何解决保活问题?以小米手机为例,MIUI的隐藏模式让不少IM和推送开发同仁纠结:MIUI深度休眠后,后台应用会默认完全断开。插座。但对于微信、QQ等应用,MIUI官方贴文表示:对这两款应用要格外小心。嗯,特意小心,普通的APP只能继续折腾了。(关于MIUI隐藏模式的讨论见本帖回复:http://www.52im.net/thread-354-1-1.html)本文实践中涉及的真机型号及版本:三星9100-4.1.2、三星9300-4.3、华为G730-4.1.2、华为TL00H-EMUI3.1(安卓5.1.1)、魅族MX4-Flyme4.2.8.2c(安卓4.4.2)。这些是手边可以使用的测试机器。主测试服务是最基础的服务,在对应生命周期的触发函数上进行输出。测试时未加入后台保护。注意:三星的机器没有找到设置后台保护的地方。为什么我们的后台进程/服务终止了?我想到了三个方面:Android系统内存回收机制;各厂商的后台程序管理系统(即允许程序在后台运行);第三方软件清理(360什么的)。部分后台程序保护结束程序同时停止程序,导致收不到广播!我们的保活计划是什么?1)控制onStartCommand函数的返回值:我对这个函数的理解是:当服务异常终止时,是否应该重启服务?有的文章在用this保活的时候修改了flag,我实际测试是无效的。有效的是直接返回参数。此外,默认标志值为0,即START_STICKY_COMPATIBILITY。具体代码如下:@OverridepublicintonStartCommand(Intentintent,intflags,intstartId){//TODOAuto-generatedmethodstubreturnSTART_STICKY;//returnsuper.onStartCommand(intent,flags,startId);}测试结果:魅族的机器无效,不管默认或者修改参数,在DDMS中直接终止进程后不会重启服务。其他三台机器(9100未测试):默认参数情况下会重启服务,返回START_STICKY会重启,返回START_NOT_STICKY不会重启。另外:360一键清理,或者360超级ROOT手机优化都会kill掉进程,过一会还是会重启,但是会慢很多,可能是排队重启的缘故服务。2)在服务的onDestory中重启服务:这个在所有可以触发onDestory的情况下都有效。4台测试机全部测试完毕。可以直接启动服务,也可以发送广播重启。但是如果能触发onDestory,不知道会不会触发内存回收。不会触发其他两种情况(2、3)。我的测试方法在“设置”->应用管理->运行->停止服务。(这是服务的正常停止,会触发onDestory,所以不会触发上面的onStartCommand效果。)3)提高服务的优先级:这个主要针对第一种kill服务,内存回收机制.因为这个测试比较难搭建。360清理杀掉所有后台进程,没有体现优先级的概念。我的建议是尽可能的改进,下面进行实验。[1]前台服务:创建通知让自己成为前台服务测试结果:360一键清理和手机优化,不会结束服务。[2]后台保护:华为G730不终止服务,魅族和华为TL00H将终止服务。通知栏的保活效果还是可以的,基本可以满足一般的应用需求。[3]如果有root权限:android:persistent="true",放入system/app测试结果:效果一般,三星9100无法用360等清理工具杀掉进程,以及它对华为G730没有影响。(这个测试有点干扰onStartCommand)。4)守护进程:双服务:360会同时杀掉两个服务,分两个apk也是一样。原生守护进程:360不会杀死原生守护进程,但在魅族和华为TL00H待机一段时间后还是会被杀死。总结及未完待续:1、一般应用加入后台保护进程后,修改onStartCommand的返回值,增加通知。基本上大部分都活下来了。2、我觉得dualservice不如nativedaemon进程。虽然360,微信等有好几个进程服务,但是如果不加到后台保活,效果就不会保活,会进入stop状态。3.然而。360手机助手会创建双natice守护进程,互相守护。生存的效果会高一点。“不加后台keepalive”一般只会被kill一次(魅族熄屏5分钟后,华为TL00H熄屏时)。Attachanativedaemon:使用socket判断服务是否存在,需要在服务中创建监听socket才能保活。调试信息会在SD卡目录下创建一个daemon.log。用法:NDKFork端口包名/.服务名。具体下载链接:http://download.csdn.net/detail/pvlking/9412815通过双进程互拉总结了Android应用保活的基本原理和设置进程的重要性,除非你root了你的自己的进程设置为系统进程。拉对方的方法有很多种:可以通过收听系统广播来拉自己。多个应用程序可以相互拉动。您可以将自己的服务变成前台服务。在服务的onstart方法中返回STATR_STICK。添加Manifest文件的属性值android:persistent="true"重写Service的onDestroy方法。服务之间相互绑定,设置闹钟,定时唤醒自己的应用。在native层fork一个子进程与主进程相互拉取。综上所述,结论是目前Android后台保活还没有完美的实现。我们只能针对不同的模型使用上面列出的方法。同时祈祷自家APP的用户不要遇到陌生机型的保活。问题。推荐一个开源方案1)源码托管地址源码托管地址为:https://github.com/52im/MarsDaemon。2)实现原理:在c端使用Jnifork进程,检测Service是否存活。如果服务已被杀死,请重新启动服务。至于检测方式,可以轮询获取子进程的Pid。如果为1,则表示该子进程被Init进程收养,成为孤儿进程。但是这种方式比较耗电,而且由于不同手机系统的自定义变化,在强行停止应用的时候,父进程可能并没有真正被杀掉,所以在一些特定的机型上无法通过这种方式判断。推荐使用liunxsocket检测类似心跳包,触发检测Service是否被kill前,需要先判断应用是否被卸载。卸载后,不再检测Service行为,直接调用exit(0)退出子进程,避免浪费系统资源和耗电。注意:目前在Android5.0系统上,fork出来的进程会被放在一个进程组中。当程序的主进程挂掉后,整个进程组也会被kill掉,所以daemon进程在Android5.0及以上系统无法通过fork实现。这是系统层面的限制,当然也是为了优化整个系统环境。守护进程给手机带来的体验并不好。详情见源码:http://androidxref.com/5.0.0_r2/.../ProcessRecord.java好消息:目前在https://github上有Android5.0及以上版本。com/52im/MarsDaemon被黑科技黑了,部分模型可能不行,但是思路值得学习,代码结构也不错,具体解决方法请参考源码。
