Android开发——Android进程保活招式大全
0. 前言
目前市面上的应用,貌似除了微信和QQ都会比较担心被用户或者系统厂商杀死的问题。Android 进程拉活包括两个层面:(1)提供进程优先级,降低进程被杀死的概率。(2)在进程被杀死后,进行拉活。本文下面就从这两个方面做一下总结。
1. 提高进程优先级方面
1.1 进程优先级介绍
Android 系统将尽量长时间地保持应用进程,但为了新建进程或运行更重要的进程,需要清除旧进程来回收内存。为了确定保留或终止哪些进程,系统会根据进程中正在运行的组件以及这些组件的状态,将每个进程赋予“重要性”。必要时系统会首先消除重要性最低的进程以回收系统资源。进程的重要性从高到低可以划分为以下五级:
(1)前台进程(Foreground process),即用户当前操作所必需的进程,通常数量不多。举例如下:
//拥有用户正在交互的 Activity(已调用 onResume())
//拥有某个 Service,后者绑定到用户正在交互的 Activity
//拥有正在“前台”运行的 Service(服务已调用startForeground())
//拥有正执行一个生命周期回调的 Service(onCreate()、onStart() 或 onDestroy())
//拥有正执行其 onReceive() 方法的BroadcastReceiver
(2)可见进程(Visible process),没有任何前台组件、但仍会影响用户在屏幕上所见内容的进程。举例如下:
//拥有不在前台、但仍对用户可见的 Activity(已调用 onPause())
//拥有绑定到可见(或前台)Activity 的 Service
(3)服务进程(Service process),尽管服务进程与用户所见内容没有直接关联,但是它们通常在执行一些用户关心的操作(例如在后台播放音乐或从网络下载数据)。举例如下:
//正在运行通过 startService() 方法启动的服务,且不属于上述两个更高类别进程的进程
(4)后台进程(Background process),后台进程对用户体验没有直接影响,系统可能随时终止它们。通常会有很多后台进程在运行,因此它们会保存在 LRU 列表中,以确保包含用户最近查看的 Activity 所在进程最后一个被终止。举例如下:
//对用户不可见的 Activity 的进程(已调用 Activity的onStop() 方法)
(5)空进程(Empty process) ,保留这种进程的的唯一目的是用作缓存,以缩短下次在其中运行组件所需的启动时间。为使总体系统资源在进程缓存和底层内核缓存之间保持平衡,系统往往会终止这些进程。举例如下:
//不含任何活动应用组件的进程
1.2 如何提高进程优先级
1.2.1 利用Activity提升权限
本方案针对第三方应用及系统管理工具在检测到锁屏事件后会杀死后台进程,已达到省电的目的问题。因此可以监控手机锁屏解锁事件,在屏幕锁屏时启动1个像素的 Activity,在用户解锁时将 Activity 销毁掉。通过该方案,可以使进程的优先级在屏幕锁屏时间提升为最高优先级。
具体实现方案如下:首先定义 Activity,并设置 Activity 的大小为1像素:
其次,从 AndroidManifest 中通过如下属性,避免 Activity 在 RecentTask 中的显示:
最后,控制 Activity 为透明:
Activity 启动与销毁时机的控制:
1.2.2 设置为前台Service
Android 中通过 setForeground 接口可以将后台Service 设置为前台 Service,使进程的优先级由4提升为2,使进程被杀死的概率大大降低。
需要注意的是,从 Android2.3 开始调用 setForeground 将后台 Service 设置为前台 Service 时,必须在系统的通知栏发送一条通知,也就是说前台 Service 与一条可见的通知是绑定在一起的。通过实现一个内部 Service,在 Service和其内部 Service 同时发送具有相同ID 的 Notification,然后将内部 Service 结束掉。随着内部 Service 的结束,Notification 将会消失,但系统优先级依然保持为2。具体实现如下:
2. 进程死后拉活方面
2.1 利用系统广播拉活
在发生特定系统事件时,系统会发出响应的广播,通过在AndroidManifest 中静态注册对应的广播监听器,即可在发生响应事件时拉活,当然也无法保证进程挂掉后立即拉活。常用的用于拉活的广播事件包括:
2.2 利用第三方应用的广播拉活
该方案总的设计思想与接收系统广播类似,不同的是该方案为接收第三方 Top 应用广播。通过反编译第三方 Top 应用,如QQ、微信、支付宝、UC浏览器等,以及友盟、信鸽等 SDK,找出它们外发的广播,在应用中进行监听,这样当这些应用发出广播时,就会将我们的应用拉活。
但是第三方应用的广播属于应用私有,当前版本中有效的广播在后续版本随时就可能被移除或被改为不外发,会影响拉活的效果。
2.2 利用系统Service机制拉活
在service的onStartCommand方法里返回 STATR_STICK,系统会重新创建这个服务并且调用onStartCommand()方法,但是它不会重新传递最后的Intent对象。但是如下两种情况无法拉活:
(1)Service 第一次被异常杀死后会在5秒内重启,第二次被杀死会在10秒内重启,第三次会在20秒内重启,一旦在短时间内Service 被杀死达到5次,则系统不再拉起。
(2)进程被取得 Root 权限的管理工具或系统工具通过forestop 停掉后无法重启。
2.4 覆写Service的onDestroy方法
必须在设置里面的正在运行里面点击关闭,会走onDestroy回调方法,可以在这里可以把自己启动起来。注意是正常关闭的时候是会自己启动起来,可是使用第三方的清理软件360,root过的360,force close这些来搞,压根不会走到onDestory的方法。
2.5 利用Native进程拉活
利用 Linux 中的 fork 机制创建 Native 进程,在 Android 中所有进程和系统组件的生命周期受 ActivityManagerService 的统一管理。通过 Linux 的 fork 机制创建的进程为纯 Linux 进程,其生命周期不受 Android 的管理。在 Native 进程中监控主进程的存活,当主进程挂掉后,在 Native 进程中立即对主进程进行拉活。
该方案主要适用于 Android5.0 以下版本的手机,并且不受 forcestop 影响。对于Android5.0 以上手机,系统不仅把主进程给杀死,另外把主进程所属的进程组一并杀死,因此native进程可能会被杀死,这里其实就是系统依次杀死进程时间与拉活逻辑执行时间赛跑的问题,如果可以跑的比系统逻辑快,依然可以有效拉起。记得网上有人做过实验,该结论是成立的,在某些 Android 5.0 以上机型有效。该方案中的几个重要问题补充如下:
2.5.1 Native 进程中如何感知主进程死亡
(1)在 Native 进程中通过死循环或定时器,轮训判断主进程是否存活,当主进程不存活时进行拉活。该方案的很大缺点是不停的轮询执行判断逻辑,非常耗电。
(2)在主进程中创建一个监控文件,并且在主进程中持有文件锁。在拉活进程启动后申请文件锁将会被堵塞,一旦拉活进程可以成功获取到锁,说明主进程挂掉,即可进行拉活。由于 Android 中的应用都运行于虚拟机之上,Java 层的文件锁与 Linux 层的文件锁是不同的,要实现该功能需要封装 Linux 层的文件锁供上层调用。
2.5.2 Native 进程中如何拉活主进程
通过 Native 进程拉活主进程的部分代码如下,即通过 am 命令进行拉活。通过指定“–include-stopped-packages”参数来拉活主进程处于 forestop 状态的情况。
2.6 利用JobScheduler机制拉活
Android5.0 以后系统对 Native 进程等加强了管理,Native 拉活方式失效。系统在 Android5.0 以上版本提供了 JobScheduler 接口,系统会定时调用该进程,使应用进行一些逻辑操作。该方案在 Android5.0 以上版本中不受 forcestop 影响,被强制停止的应用依然可以被拉活,在 Android5.0 以上版本拉活效果非常好。仅在小米手机可能会出现有时无法拉活的问题。
2.7 利用帐号同步机制拉活
Android 系统的账号同步机制会定期同步账号进行,该方案目的在于利用同步机制进行进程的拉活。Android系统里有一个账户系统,设置一个自己的账户,系统会定期唤醒账户更新服务,我们可以自己设定同步的事件间隔。且发起更新的是系统,不会受到任何限制。
添加账号和设置同步周期的代码如下:
该方案需要在 AndroidManifest 中定义账号授权与同步服务。
Android N中系统对账户同步做了变动,该方案适用于除Android N以外所有的 Android 版本,包括被 forestop 掉的进程也可以进行拉活。
可是它还是有如下的局限性:
(1)从用户角度来说,用户会在系统设置的账户列表里面看到一个不认识的账户;而且某些手机比如note3需要手动设置账户,你如何骗你的用户给你手动设置账户完了之后不卸载你;
(2)从设备商角度看,同步的事件间隔是有限制的,最短1分钟,见源码,而且各种国产机怎么改的源码我们未知,是不是都能用仍然未知;
(3)从Google的角度来看,Google提供这个组件是让你同步账户信息,必须联网,不联网则无法同步。
2.8 推送拉活
根据终端不同,在小米手机(包括 MIUI)接入小米推送、华为手机接入华为推送,可以作为拉活方案的有效补充。
感谢:
http://dev.qq.com/topic/57ac4a0ea374c75371c08ce8
http://blog.csdn.net/yyh352091626/article/details/50542554
http://blog.csdn.net/two_water/article/details/52126855
Android开发——Android进程保活招式大全的更多相关文章
- 【腾讯Bugly干货分享】Android进程保活招式大全
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57ac4a0ea374c75371c08ce8 作者:腾讯——张兴华 目前市面上 ...
- Android 进程保活招式大全
目前市面上的应用,貌似除了微信和手Q都会比较担心被用户或者系统(厂商)杀死问题.本文对 Android 进程拉活进行一个总结. Android 进程拉活包括两个层面: A. 提供进程优先级,降低进程被 ...
- Android 进程保活招式大全(转载)
目前市面上的应用,貌似除了微信和手Q都会比较担心被用户或者系统(厂商)杀死问题.本文对 Android 进程拉活进行一个总结. Android 进程拉活包括两个层面: A. 提供进程优先级,降低进程被 ...
- 【转载】Android进程保活招式大全
原文地址:http://dev.qq.com/topic/57ac4a0ea374c75371c08ce8 目前市面上的应用,貌似除了微信和手Q都会比较担心被用户或者系统(厂商)杀死问题.本文对 An ...
- Android开发——Android多进程以及使用场景介绍
个层级,具体可以查看Android开发--Android进程保活招式大全中1.1部分的内容,这里就不赘述了. 根据进程中当前活动组件的重要程度,Android 会将进程评定为它可能达到的最高级别.例如 ...
- Android开发-Android Studio问题以及解决记录
[Android开发] Android Studio问题以及解决记录 http://blog.csdn.net/niubitianping/article/details/51400721 1.真 ...
- Android开发——Android M(6.0) 权限解决方案
Android开发--Android M(6.0) 权限解决方案 自从Android M(6.0)发布以来,权限管理相比以前有了很大的改变,很多程序员发现之前运行的好好的Android应用在Andro ...
- Android 开发学习进程0.28 腾讯TBS接入和相关问题
TBS 的接入和使用 TBS 的接入 腾讯TBS是X5内核的升级版,可以当作webview 来打开 网页,可以以用来打开docx doc pdf 等文件,这里主要使用的是文件功能. 依赖接入 api ...
- Android 开发学习进程0.19 webview 的使用
Android 中的webview android 中的webview是可以在app内部打开HTML等的网页,不必再打开浏览器,有两种实现方法,即webviewclient webChromeclie ...
随机推荐
- 【jdk源码2】Objects源码学习
在学习上一个类TreeMap的时候,提到了这个类,这个类是jdk1.7新增的,里面有很多实用的方法.就是一个工具类,熟悉以后,如果里面有已经实现的方法,那么就不要再去实现了,省时省力省测试. 一.简单 ...
- Windows桌面.exe程序安装、卸载、升级测试用例
一.安装 1) 系统:XP.win 7.win 8.win 10 2)安全类型软件:360杀毒.360安全卫士.金山毒霸.百度杀毒.腾讯电脑管家等. 3)同类型软件兼容 4)用户名称:中文用户.英文用 ...
- 数据分析——Matplotlib图形绘制
创建画布或子图 函数名称 函数作用 plt.figure 创建一个空白画布,可以指定画布大小,像素. figure.add_subplot 创建并选中子图,可以指定子图的行数,列数,与选中图片编号. ...
- 负载均衡(Load Balancing)学习笔记(二)
概述 文章负载均衡(Load Balancing)学习笔记(一) 讲述了负载均衡的一般性原理,本文继续介绍常见的实现负载均衡的方法. HTTP重定向 HTTP重定向服务器是一台普通的Web服务器,用户 ...
- “由于这台计算机没有终端服务器客户端访问许可证”解决方案
由于windows2003默认仅支持2个终端用户的登陆.当"终端连接超出了最大连接"的情况出现导致不能登录. 1.在另外一台Windows2003的机器上运行"tsmmc ...
- python自定义函数和推导
#之所以把这俩写一起,并不是因为这俩有什么关系,因为都太简单,没什么可说的 #自定义函数的格式,def开头,后面空格,在后面是函数名,接括号,括号里是入参参数 #!/usr/bin/python # ...
- tar压缩/解压用法
格式:tar zcvf 压缩后的路径及包名 你要压缩的文件 z:gzip压缩 c:创建压缩包 v:显示打包压缩解压过程 f:接着压缩 t:查看压缩包内容 x:解压 X:指定文件列表形式排除不需要打包压 ...
- 一起学习Boost标准库--Boost.StringAlgorithms库
概述 在未使用Boost库时,使用STL的std::string处理一些字符串时,总是不顺手,特别是当用了C#/Python等语言后trim/split总要封装一个方法来处理.如果没有形成自己的com ...
- Skype 服务器客户端策略参数优化
1.skype通讯录原理 对于skype客户端的通讯录同步,首先说说原理,通讯簿信息是从AD同步的skype前端服务器(每天1:30),在从前端服务器同步的客户端(大概1小时内同步一次). skype ...
- 如何使用EditPlus批量删除 带有某个字符的一行
比如以下五行,我要将带有英文字母a的一行全部批量删除1234551243243123aa244123123981232137aa 2013-04-11 19:32 提问者采纳 我这里是英文版, ...