探讨Android6.0及以上系统APP常驻内存保活实现

  • 时间:2017-07-16
  • 分类:Android开发
  • 1350 人浏览
[导读]APP常驻内存(保活),旧事重提,距离上一次的研究亦有半年有余。最近,用户反馈说多进程守护方案在华为Mate8(7.0)保活效果不是很好,有时候还是不能及时收到消息,于是,又带着怀疑的 光,重新找回原来的代码进行测试,顺便分析了市场上主流运动类APP保活方法(微信、手Q就算了,富人家的孩子,不具代表性),同时也对系统对内存中APP的管理规则进行了进一步探索。

(1) 探讨一种新型的双进程守护应用保活方法
(2) 探讨Android6.0及以上系统APP常驻内存(保活)实现-争宠篇
(3) 探讨Android6.0及以上系统APP常驻内存(保活)实现-复活篇
       APP常驻内存(保活),旧事重提,距离上一次的研究亦有半年有余。最近,用户反馈说多进程守护方案在华为Mate8(7.0)保活效果不是很好,有时候还是不能及时收到消息,于是,又带着怀疑的 光,重新找回原来的代码进行测试,顺便分析了市场上主流运动类APP保活方法(微信、手Q就算了,富人家的孩子,不具代表性),同时也对系统对内存中APP的管理规则进行了进一步探索。本文便是对最近一周的探索、学习、测试的总结之一,以备将来不时之需。
一、APP保活核心思想归纳
     对于Android6.0及其以上系统APP保活,我觉得主要还是通过这两个方面进行,即:降低omm_adj ,尽量保证进程不被系统杀死;进程被杀死后,通过其他方式将进程复活。但需要明白的是,面对各手机厂商的深度定制和谷歌越来越严 的资源管理机制,这两种方式结合的保活不是永久的,只能是相对存在,不同的机型结果也是不一样的。

由于篇幅限制,本文主要剖析下通过何种方式降低oom_adj的 来降低APP被杀的几率,以及oom_adj 是怎样做到的?接下来,我们需要了解下Android系统回收内存中的进程所依据的规则:进程在内存中时活动主要有五种状态,即前台进程、可见进程、服务进程、后台进程、空进程,这几种状态的进程优先级由高到低,oom_adj 由低到高(在ProcessList定义),然后Android系统会根据当前系统资源和进程oom_adj 来回收相应的进程,前台进程一般不会被回收,空进程最容易被回收,这种管理规则就是 传说中 的Low Memory Killer。为了更直观的了解这套规则,我画了个表:


注:优先级1表示最高级,普通进程的oom_adj =0,系统进程oom_adj 0,系统会根据相应的内存阀 对符合某段oom_adj 的进程进行回收。另外,oom_adj 也会随着占用物理内存越大而增大,系统进程绝对不会被系统杀死。
二、市场主流运动类APP分析
1. 咕 咚(v 7.17.0)
(1) 一键清理/滑动清理
a. 当 咕咚 处于停止状态,其进程被杀死,通知栏图标被清理,等待几分钟没有 自动重启,当重新进入“咕咚”时,会从欢迎界面重新进入;
b. 当 咕咚 处于运动进行状态,进程死亡,通知栏图标被清除,等待几分钟没有自动重启,但当重新进入“咕咚”时,其直接显示运动界面,而没有从欢迎界面进入,运动时间等状态与被清理时一样;
c. 当 咕咚 处于运动暂停状态,其进程正常存活,通知栏图标正常显示。如果是单独清理,进程死亡,通知栏图标被清除;但当重新进入“咕咚”时,其直接显示运动界面,而没有从欢迎界面进入,运动时间等状态与被清理时一样;
(2) 黑屏/锁屏
a. 当 咕咚 处于停止状态,退到后台,锁屏进入黑屏状态,等待5分钟,进程死亡,通知栏被清除;
b. 当 咕咚 处于运动进行状态,退到后台,锁屏进入黑屏状态,然后再进入系统,“咕咚”跑步界面自动弹出。再次锁屏,等待20分钟,进程没有被杀死, 咕咚 跑步界面自动弹出,运动状态保持不变;
c. 当 咕咚 处于运动暂停状态,退到后台,锁屏进入黑屏状态,然后再进入系统, 咕咚 跑步界面自动弹出。再次锁屏。等待20分钟,进程没有被杀死, 咕咚 跑步界面自动弹出,运动状态保持不变;
* 前提: 手机管家- 锁屏清理应用 关闭;
                手机管家- 自启管理 关闭;
                运动状态,禁用返回键,用户只能从Home键退到后台
                运动界面文字闪烁或运动计时
                断网
* 分析:当 咕咚 处于停止状态时,一键清理和黑屏状态会被杀死,说明在没有进入运动界面之前,其保活机制没有被启动(即没有使运动界面切换到后台等)。当“咕咚”处于运动状态时,一键清理和黑屏状态没有被杀死(滑动清理除外),说明已经启动保活机制:① 咕咚 禁止了返回键,以保证运动Activity不被销毁;②不断更新通知栏计时,以保证APP始终在前台,防止被系统回收;③ 咕咚 被清理后能够自动重启,通知被删除后自动弹出,说明可能有另外一个东西(进程或Service)监听器运动Service(或进程)存活状态,当Service被销毁时,立马将其拉起来;④“咕咚”被强制停止或清理杀死后,再次进入会直接显示运动界面且能够保持杀死之前的运动状态,说明其可能利用配置文件记录了相关状态;⑤锁屏/解锁后, 咕咚 运动界面会自动弹出,说明其利用了广播机制对锁屏广播进行监听,弹出Activity以保证进程始终在前台;
* 结论:常驻通知栏,双进程守护,广播锁屏,自定义锁屏
* 备注:以上为华为Mate8(7.0)测试结果;其他如三星C9(6.0)保活较好,特别是当一键清理时, 咕咚会自动启动,估计是使用了进程守护策略,而三星使用的是原生系统,因此结果你懂得;360F4(6.0)保活很差,不愧是流氓中的战斗机,以更流氓的方式干掉流氓APP;
2. 乐动力(v7.3.2)
(1) 一键清理 / 滑动清理
      三星C9(6.0):无论何种状态, 乐动力 进程被杀死,等待几分钟,没有自动启动;
      360F4(6.0):无论何种状态, 乐动力 进程被杀死,等待几分钟,没有自动启动;
      华为Mate8(7.0):无论何种状态, 乐动力 进程被杀死,等待几分钟,没有自动启动;
(2) 锁屏/黑屏
 a. 当 乐动力 处于停止状态,退到后台,锁屏,等待5分钟,进程死亡,通知栏被清除;
 b. 当 乐动力 处于运动暂停状态,退到后台,锁屏再开启,运动界面被切换到前台,并强制弹出自定义锁屏界面(覆盖在系统锁屏界面之上);再次锁屏,等待20分钟,应用进程存活;
 c. 当 乐动力 处于运动进行状态,退到后台,锁屏再开启,运动界面被切换到前台,并强制弹出自定义锁屏界面(覆盖在系统锁屏界面之上);再次锁屏,等待20分钟,应用进程存活;
* 前提: 手机管家- 锁屏清理应用 关闭;
                手机管家- 自启管理 关闭;
                运动状态,禁用返回键,用户只能从Home键退到后台
                断网
* 分析:当 乐动力 处于停止状态时,黑屏状态下,其在短时间内被系统杀死,说明保活机制没有启用;但当处于运动暂停或进行状态时, 乐动力 在一段时间内没有被杀死,且当锁屏时, 乐动力 会自动将运动界面切换到前台,此外,还会强制弹出自定锁屏界面,这就说明 乐动力 的保活机制很可能是利用监听锁屏广播强制将相关界面切换到前台,以提高 乐动力 在黑屏状态下的存活率。
* 结论:常驻通知栏,广播锁屏,自定义锁屏
3. 悦动圈(v3.1.2.9)
(1) 一键清理 / 滑动清理
      三星C9(6.0):效果与乐动力一致;
      360F4(6.0):效果与乐动力一致;
      华为Mate8(7.0):效果与乐动力一致;
(2) 锁屏/黑屏
a. 当 悦动圈 处于停止状态,退到后台,锁屏,等待3分钟,进程死亡,通知栏被清除;
b. 当 悦动圈 处于运动暂停状态时,自定义锁屏、切换界面到前台与咕咚、乐动力一样,效果一致;
c. 当 悦动圈 处于运动进行状态时,自定义锁屏、切换界面到前台与咕咚、乐动力一样,效果一致;
* 结论:常驻通知栏,广播锁屏,自定义锁屏
三、APP保活方案探讨
    经过上面的讨论分析, 咕咚 、 乐动力 等这类APP主要是通过监听锁屏、网络等系统广播,将进程置于前台以提高进程的级别,从而防止进程不那么轻易被系统干掉。另外, 咕咚 可能还使用了相关的进程被清理复活策略。当然,对于复活策略,我们下一篇文章再探讨,本文主要讨论以上APP是通过哪些方式降低进程omm_adj ,防止其被系统杀死的。
    为了达到与 咕咚 等APP类 效果,我们模拟这么一种场景:当用户登录测试APP后,先不开启保活功能;当用户开始跑步时,开启保活功能,然后再在这基础上做黑屏运行、一键清理、强制停止等功能测试。也就是说,Android项目中SplashActivity、LoginActivity只是配合我们 演戏 的,真正启动APP保活逻辑的是在SportsActivity,它将上演 后宫争宠 戏码。
     好吧,小伙子,开始你的表演!
1. 开启前台Service,“ 君上位”
    将Service置为前台,目的时提高进程Service的oom_adj ,以降低其被系统回收的几率。该方案的原理是,通过使用 startForeground()方法将当前Service置于前台来提高Service的优先级。需要注意的是,对API大于18而言 startForeground()方法需要弹出一个可见通知,如果你觉得不爽,可以开启另一个Service将通知栏移除,其oom_adj 还是没变的。实现代码如下:
a) DaemonService.java

来源:本文为线上采编,如涉及作品内容、版权和其它问题,请及时与本网联系,我们将在第一时间删除!