Android程序保活

要点

1、程序被杀的原因

2、系统回收程序机制

3、提高程序存活率的方法探究

 

 

程序被杀的原因

(1)程序在后台内存不足时被杀,或者后台存活程序数量被限制

(2)程序被第三方管理软件清理,比如360CleanMaster

(3)程序被用户手动清理,比如小米自带的系统一键清理、手机设置里应用管理器的ForceClose

 

 

系统回收程序机制

Android程序运行机制

Android是一个多任务系统,启动运行一个程序是有一定的时间开销的,因此为了加快运行速度,当你退出一个程序时,Android并不会立即杀掉它,这样下次再运行该程序时,可以很快的启动

当系统中保留的程序越来越多时,内存会越来越少。low memory killer就是在系统内存低于某个阈值时,开始清理一些内存程序,保证有一定的内存空闲。

 

low memory killer

Android Low memory killer是基于linuxOOMout of memory  规则改进而来的。 OOM通过一些比较复杂的评分机制,对进程进行打分,然后将分数高的进程判定为bad进程,杀死并释放内存。OOM只有当系统内存不足的时候才会启动检查,而Low memory killer 则是定时进行检查

 

释放的规则

Low memory killer根据两个原则,进程的重要性和释放这个进程可获取的空闲内存数量,来决定释放的进程

(1)进程的重要性,oom_adj决定,查看方法:ps |grep 包名/proc/pid/oom_adj,在系统中位置是/sys/module/lowmemorykiller/parameters/adj

名称

含义

内存阈值(4K为单位)

(具体值与手机相关)

NATIVE_ADJ

-17

Native 进程(不被系统管理)

 

SYSTEM_ADJ 

-16

系统进程

 

CORE_SERVER_ADJ

-12

系统核心服务

 

PERSISTENT_SERVICE_ADJ

-11

关联着系统或persistent进程,比如telephony

 

FOREGROUD_APP

0

前台程序,可以理解为你正在使用的程序 

1536 

VISIBLE_APP

1

用户可见的程序 

2048 

SECONDARY_SERVER

2

后台服务 

4096 

BACKUP_APP_ADJ

3

备份进程

 

HOME_APP

4

     HOME,就是主界面 

5120 

SERVICE_ADJ

5

服务进程

 

HOME_APP_ADJ

6

Home进程

 

HIDDEN_APP

7

被隐藏的程序 

5632 

SERVICE_B_ADJ

8

B List 中的Service

 

CACHED_APP_MIN_ADJ

9

不可见进程

 

CONTENT_PROVIDER

14

内容提供者

6144

EMPTY_APP

15

 空程序,既不提供服务,也不提供内容

 

 


   (2)进程内存,在相同的oom_adj条件下,内存越大,优先被清理掉。在系统目录/sys/module/lowmemorykiller/parameterscat minfress可以查看各个进程类型的斩首阈值

 

提高程序存活率的方法探究

        

1Service相关方法

(1)    serviceonStartCommand中返回START_STICKY

(2)    serviceonDestroy中启动自己,正常走onDestroy方法才有效

(3)    配置serviceandroid:persistent=“true”,这个需要系统签名才可以

 

2、提升优先级

(1)    启动前台service:利用系统的漏洞来启动一个前台的Service进程,与普通的启动方式区别在于,它不会在系统通知栏处出现一个Notification,看起来就如同运行着一个后台Service进程一样。这样做带来的好处就是,用户无法察觉到你运行着一个前台进程(因为看不到Notification,但你的进程优先级又是高于普通后台进程的

(2)    锁屏时开启一个像素的Activity,解锁时关闭这个页面,达到用户无感。把进程提升为可见进程

这种方法,用户强制杀掉程序以及第三方软件清理后,都无法启动。

 

3、拉起程序

(1)监听广播事件,检测进程是否存活,然后拉起。比如:开机广播、网络变化、屏幕亮灭、屏幕解锁、文件挂载、电源连接。 广播接收器被管理软件、系统软件通过自启管理等功能禁用的场景无法接收到广播,从而无法自启。
系统广播事件不可控,只能保证发生事件时拉活进程,但无法保证进程挂掉后立即拉活。

 

(2)跨进程bind一个service之后,如果被bindservice挂掉,bind他的service会把他拉起来。这种方法,被清理后,都启动不了

 

(3)使用闹钟定时器,定时唤醒。使用AlarmManager,这种方法耗电,而且被强制杀掉后,没有机会再起来

 

(4)接入第三方推送,第三方推送会有群体拉起功能。比如极光推送、个推推送,只要手机里打开了已经接入这些推送的程序,则会唤醒所有接入同一个推送的程序。BAT系的大厂,都有这种相互唤醒的机制,比如打开支付宝,会有淘宝、UC浏览器等的推送过来

 

(5)厂商白名单。大厂会跟大的手机厂商合作,把需要守护的进程加到系统进程级别,被杀后也可以立即起来。

 

(6)利用Native进程拉活。

有两种实现方案,一种是循环监听主进程是否存活,一旦被杀则启动,这种方式非常耗电,不推荐。

 

第二种方案是:在主进程中创建一个监控文件,并且在主进程中持有文件锁。在拉活进程启动后申请文件锁将会被堵塞,一旦可以成功获取到锁,说明主进程挂掉,即可进行拉活。由于 Android中的应用都运行于虚拟机之上,Java层的文件锁与 Linux层的文件锁是不同的,要实现该功能需要封装 Linux层的文件锁供上层调用。

这种方法不受强制关闭的影响,5.0以下版本有效,5.0版本以后系统对Native进程加强了管理,无效

(7) 利用 JobScheduler拉活:Android5.0以上版本提供了 JobScheduler接口,系统会定时调用该进程以使应用进行一些逻辑操作,可以尝试

 

(8)利用账号同步机制拉活。android系统里有一个账户系统,设置一个自己的账户,android会定期唤醒账户更新服务,首先要设置一个账户才行。用户会在账户系统中看到一个不认识的账号

 

(9)GCM推送(Google Cloud Messaging)谷歌云消息,类似苹果的Apns服务。但是国行手机基本上缺少系统组件,并且网络限制连接不上GCM服务器。国外用户可以接入

 

(10)手机大厂的推送,比如小米推送,华为推送

 

主要对策:

1、  以上方法能试的都给试试

2、 小米华为推送接入

3、 国外的接入GCM

4、 减少内存使用,降低被杀风险

5、 拆分进程

 

参考阅读

http://www.cnblogs.com/imstudy/p/5674480.html Android后台保活实践总结:即时通讯应用无法根治的顽疾

http://www.infoq.com/cn/articles/wechat-android-background-keep-alive#anch135151 微信Android客户端后台保活经验分享

http://blog.csdn.net/marswin89/article/details/48015453 Android进程常驻(1----开篇

http://zhoujianghua.com/2015/07/28/black_technology_in_alipay/ 支付宝后台不死的黑科技

http://www.jianshu.com/p/63aafe3c12af#  关于 Android进程保活,你所需要知道的一切 

你可能感兴趣的:(android,我在Android开发)