在安卓中调用Service的startForeground方法可以将service所在进程的优先级提高,减小进程被回收的概率。
调用startForeground方法的时候系统会在通知栏显示一个通知,这对于传统的多媒体应用来说是没有问题的。
但是对于那些只想提升优先级而不想让用户感知的应用来说强行显示个通知栏看起来太怪异了。
查看startForeground的源码之后,发现有很重要的两步,如下所示:
那么我们有没有办法能让updateServiceForegroundLocked执行成功,而让postNotification()执行失败呢?
进一步查看postNotification()方法:
由上可知,只要enqueueNotification执行出现异常,通知栏则不会显示通知了,但是此时却会导致应用进程crash调用。
那么如何使得crashApplication这个方法失效呢,我们进一步查看crashApplication方法的代码:
|
|
|
|
我们现在已经知道了ams是如何让我们的进程crash的了,基本就是ams跟我们应用进程说,你准备准备该去死了,然后应用进程就去死了。
但是做为一个有个性的进程,能不能在ams让他去死的时候假装没听见呢?显然是可以的,基本的流程就是:
- 先拿到ActivityThread的实例
- 拿到ActivityThread$H 的实例mH
- 向mH设置一个Handler.Callback
- 在Handler.Callback 中检测到 SCHEDULE_CRASH消息时则消费该消息
具体实现代码如下所示:
这里写了一个工具类方便大家使用:RaisePriorityHack