Android 黑科技之让进程不被杀掉

Android 黑科技之让进程不被杀掉

目前市面上,除了微信和手Q外,都会想尽办法能够保证自己的应用进程不被杀掉,其实鹅厂的不被杀掉不是他们使用了什么黑科技,而是手机厂商给鹅厂做了优化,没办法,谁让现在有人不用鹅厂的东西吗?

不信可以放到 Nexus 手机上,保证当内存紧张的时候,绝B一样杀掉。

回到正题,所谓的黑科技,也就是利用一些不正当的方式,尽最大的可能保留我们的应用的优先级,从而不被轻易杀掉。

Android 进程保持活着,这里有两个层面的意思:

A. 提高进程优先级,降低被杀死的概率

B. 被杀死后,可以被系统重调用起来

进程优先级

这里提到了进程优先级,那么什么是进程优先级呢?

Android 在设计之初,就有考虑到如何能够快速的启动一个应用。所以当退出一个应用的时候,其实这个应用并没有真的被回收,这样如果再次启动,可想而知,会很快就被启动起来。但是,为了新建进程或运行更重要的进程,那么必然需要清除旧进程来回收内存。那么到底哪些重要,哪些可以来回收呢? Android 对此有做一个分类,优先级共划分为5层:

  1. 前台进程

  2. 可见进程

  3. 服务进程

  4. 后台进程

  5. 空进程

其重要性或者优先级也是依次递减,空进程重要性最低。

前台进程

这个比较好理解,最直接的例子就是当前处于前台的 Activity,基本上不会出现你正在操作一个应用的时候,突然间被系统关闭了,除非内存真的低到不行。

那么除了 Activity 外,是否其他的控件也可以是被看作前台呢? Service 也可以,但是前提是这个service 被正在交互的 Activity 绑定,或者 Service 在一开始声明自己是前台 Service(会显示一个Notification给用户,这个在2.3的时代是最普遍的用法,当时notification都不会显示给用户)。最后,正在执行 onReceive() 方法的broadcastReceiver 也会被系统认为是前台进程。

可见进程

和前台进程相比,可以理解为调用了 onPause() ,但是没有执行 onStop() 的 Activity,仍然非常重要。

服务进程

音乐播放器就属于这类,虽然没有和用户交互的操作,但是后台播放音乐仍然是很重要的,所以除非内存不足以维持所有前台进程和可见进程同时运行,否则系统会让服务进程保持运行状态。

后台进程

后台进程对用户体验没有直接影响,系统可能随时终止它们,以回收内存供前台进程、可见进程或服务进程使用。比如调用了 onStop() 的 Activity。

空进程

不含任何活动应用组件的进程。保留这种进程的的唯一目的是用作缓存,以缩短下次在其中运行组件所需的启动时间。

搞清楚了进程的类型,那么接下来就是 Android 系统是怎么来对这几种进程分类,已经又是根据什么规则来判断哪些该杀,哪些不该杀呢?

进程回收策略

这个策略,Android 世界中的名称叫做 Low Memory Killer,我们的应用都是被他给无情的从内存中抹杀了啊!

其实说这个策略,也很简单,系统会根据一个阀值,OOM_ADJ,不同的阀值来触发相应的回收力度。

关于 OOM_ADJ 的说明如下:

Android 黑科技之让进程不被杀掉

红色就是很容易被干掉的进程(OOM_ADJ >=4), 越大越代表不重要。在 Lowmemorykiller 回收内存时,会根据进程的级别优先杀死 OOM_ADJ 比较大的进程,对于优先级相同的进程则进一步受到进程所占内存和进程存活时间的影响。

其实到这里,黑科技是想办法提高进程优先级,减少进程在内存不足等情况下被杀死的概率。

你现在应该知道鹅厂的应用为什么不会被杀掉了吧?因为手机厂商把他们都加入到了系统进程中。

明白了原理,下面来看我们的黑科技。

利用 Activity 提升权限

  • 设计思路

    监控手机锁屏解锁事件,在屏幕锁屏时启动1个像素的 Activity,在用户解锁时将 Activity 销毁掉。注意该 Activity 需设计成用户无感知。

    通过该方案,可以使进程的优先级在屏幕锁屏时间由4提升为最高优先级1。

  • 使用范围

    本方案主要解决第三方应用及系统管理工具在检测到锁屏事件后一段时间(一般为5分钟以内)内会杀死后台进程,已达到省电的目的问题。

  • 具体实现

    Android 黑科技之让进程不被杀掉

    Android 黑科技之让进程不被杀掉

    Android 黑科技之让进程不被杀掉

利用 Notification 提升权限

  • 设计思路

    通过 setForeground 接口可以将后台 Service 设置为前台 Service,使进程的优先级由4提升为2,从而使进程的优先级仅仅低于用户当前正在交互的进程,使进程被杀死的概率大大降低。

  • 实现方式

    本身前台 servcie 的使用不复杂,但是因为 4.x 版本后会强制显示 Notification,因此这里需要会钻一个 Notification 的漏洞,即在 Service 内部再实现一个service,然后此内部service发送一个和前台 Servcie ID 相同的 Notifcation,然后在自己结束自己,这样 Notification就被从 Notification manager 中移走了,不过在 Android 7.1 中,Google 已经堵上了这个漏洞,但是 7.1 的普及至少还有一年,所以还是可以继续使用这个方式,代码的具体实现可以百度.

被杀死后再被重启

所谓道高一尺魔高一丈,系统虽然想尽办法来限制应用,但是总能利用系统的一些功能来为我所用。

  • 使用系统广播来重启

    在发生特定系统事件时,系统会发出响应的广播,通过在 AndroidManifest 中“静态”注册对应的广播监听器,即可在发生响应事件时拉活。

    但是这个方法目前是被 Google 堵的越来越死,因为基本上现在很多的广播都不再支持静态注册了,但是你仍然可以尝试看看,特别是老的 Android 版本都还可以使用。

  • 使用第三方应用广播

    相比第一个,这个是目前仍然可以使用且短期 Google 从源码上很难堵上的方案。

    通过反编译第三方 Top 应用,如:手机QQ、微信、支付宝、UC浏览器等,以及友盟、信鸽、个推等 SDK,找出它们外发的广播,在应用中进行监听,这样当这些应用发出广播时,就会将我们的应用拉活。

  • 利用 JobScheduler 机制

    Android5.0 以上版本提供了 JobScheduler 接口,系统会定时调用该进程以使应用进行一些逻辑操作。

  • 利用账号同步机制拉活

    Android 系统的账号同步机制会定期同步账号进行,该方案目的在于利用同步机制进行进程的拉活。

其他还有一些技术之外的措施,比如说应用内 Push 通道的选择:

  1. 国外版应用:接入 Google 的 GCM。

  2. 国内版应用:根据终端不同,在小米手机(包括 MIUI)接入小米推送、华为手机接入华为推送;

其实,从规范上来讲,应用应该遵从编码规范,但是在实际项目的时候,PM 是不会和你讨论这个,用户也不会想知道这些,所以苦逼的我们只能不断的去钻空子啊!!!
展开阅读全文

没有更多推荐了,返回首页