Android开发 保证软件不被杀死的1001种方法

呵呵,标题只是吸引大家点进来而已,切勿当真。

大家知道作为一个合格的国产流氓手机软件,不能后台自启、不能唤醒全家桶、不能顽强到杀不死、不能保持连接,是会被大家鄙视的。

现在越来越多的大企业加入了全家桶行列,像什么百度啊、腾讯啊、阿里啊、 易啊,现在路子都挺野的,如果不给手机装个冰箱、绿色啥的,随手打开一款软件,状态栏随时会蹭蹭蹭冒出一大堆通知消息,不仅如此,当你尝试按正常步骤退出软件、甚至清掉后台UI进程,很可能过一会它还会冒出消息来。

没有错,国产软件就是这么嚣张贴心,生怕你会错过什么广告消息。

好了,闲话少扯,比如我们要出一款流氓通讯软件,做好软件保活还是很重要的,要不客户经常掉线,分分钟丢掉几十万dollar,下次还会使用你么

大家在集成一些推送或者分享SDK(如极光推送、微信分享)时,会有许多应用后台自启的问题,对于推送类SDK是因为它采用了单通道的模式,也就是说所有集成了同一推送SDK的应用其中任意一个收到消息时其他的也会被唤醒,这是为了保证推送的成功率,否则那些已经挂掉的软件经常收不到推送消息会考虑换掉推送SDK。而例如微信之类推出的分享SDK则是在打开集成分享的软件时通过发送广播启动自家应用。

先来普及一下安卓与此相关的一些相关概念:

Android系统按照进程的优先级分为:

1. 前台进程(Forgroud process): 顶层activity(已执行onResume); 有个Service,并绑定到跟用户正在交互的activity;在Service里调用了startForground函数;正在执行onReceive函数的BroadCastReceiver。

2. 可见进程(Visible process): 被对话框遮挡的activity, 执行了onPause; 拥有绑定到Activity的Service, 但该Activity被遮挡了, 例如按Home键,并执行了onStop。

3. 服务进程(Service process): 有正在运行的Service, 但是没有1/2的特性。

4. 后台进程(Background process)没有正在运行的Service, 只有不可见的Activity, 即Activity执行了onStop函数。

5. 空进程(Empty Process), 不含Android 4大组件的进程。

按照Android的设计, app只能提高自己的进程优先级, 降低被杀掉的概率。

而在Android 的4大组件中,Activity因为与界面相关,所以它的生命周期只有在前台或者可见时才能有所保障,而ContentProvider则是用来进行数据操作的,需要搭配ContentResolver使用,生命周期自行管理,在此也不做讨论。那么程序保活的重担就落在Service和BroadCastReceiver身上了。

先说BroadCastReceiver,通过它来保活,处理方式比较单一,一般都是监听系统广播,如ACTION_NEW_PICTURE,ACTION_NEW_VIDEO,CONNECTIVITY_ACTION,action.BOOT_COMPLETED等,并在接收方法里启动相应守护服务。

至于Service,则有很多要讲的。

1,Service设置成START_STICKY(onStartCommand方法中),kill 后会被重启(等待5秒左右),重传Intent,保持与重启前一样,但是内存过低或者进程被kill时容易失效。

2,提高Service优先级,即通过startForeground将Service设置为前台服务,同样内存极低时会被kill。

3,在onDestory里面重启Service,有一个问题是当进程被第三方应用或者在设置里强制终止时会不走onDestory,所以也是无法完全保证。

4,通过不显示通知栏图标的前台服务,将app悄悄保留在后台。

AndroidManifest当中设置:

当然,这个方法只能算提高了进程优先级。如果你的app进程占用了大量的系统资源,按照系统进程回收的策略,同样会kill你的app。

通过adb shell,然后输入下面的shell命令

dumpsys activity services PackageName

打印出指定包名的所有进程中的Service信息,看下有没有 isForeground=true 的关键信息。如果通知栏没有看到属于app的 Notification 且又看到 isForeground=true 则说明了,此app利用了这种灰色保活的手段。

除了广播接收器和服务之外,其他的方法还有:

1,5.0之前,可以采用双进程拉起,这种方式就是传说中的使用NDK在底层fork出一个子进程,来实现与父进程之间的互拉。在Android4.x还是非常有效的,但是高版本的Android系统的系统回收策略已经改成进程组的形式了,如果系统要回收一个应用,必然会杀死同属于一个进程组的所有进程,因此最后导致双进程无法拉起。

2,接入第三方SDK唤醒相应的app进程,如微信sdk会唤醒微信,支付宝sdk会唤醒支付宝,并唤醒全家桶关联应用。

3,5.0及以上使用JobSheduler机制保活,测试发现很多机型无效。

4,联系厂商,加入白名单,有童鞋验证把demo工程的包名改成手机QQ的,编译运行在华为的机子上,发现进程杀不死,退到后台oom_adj的值同样不发生变化,而恢复原来的包名就不行了,可见很多大型软件,尤其聊天类的都会和厂商合作,将相关应用加入白名单。

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2016年11月6日
下一篇 2016年11月6日

相关推荐