安卓的后台机制既是安卓的一个优势,也是碎片化很严重的一个特性,作为三款依赖安卓后台服务的App的开发者,写下这篇文章来比较一下EMUI和MIUI这两个最常见的安卓系统的后台处理逻辑,先把要比较的系统列一下:
比较后台机制的前提是两个系统均使用缺省设置,不考虑诸如省电模式、极简模式等特殊情况,这样符合大部分用户的使用情况。
常见的安卓App驻留后台方式有三种:
这三种后台模式,我都开发过相应的App,下面会分别举例来比较。除此以后,还有一些匪夷所思,也非官方认可的谋取驻留后台的方式,比如播放一个无声的音乐、开启一个单像素的悬浮窗等等,毕竟不属于正道,本文就不比较了。
在比较之前,有必要说明一下,对于现在各厂商安卓系统,比如我们要比较的EMUI和MIUI,仅仅按照这种正规方式注册服务是不够的,还是很容易被系统冻结或杀掉,原因是因为按正规方式注册服务,所有的应用都可以做到,后台多了,加上一些应用没有节制,手机就必然卡顿费电,所以厂商们的做法也很好理解,默认全杀,做一个只能手工配置的白名单,用户加入白名单才允许后台服务,这样对于大部分普通用户,不用做任何设置就免受恶意软件之苦。
需要注意,不同系统白名单配置稍有不同:
下面开始测试三种后台方式。
我开发的微动手势,就是一个典型的无障碍服务类应用,安卓系统支持应用注册为无障碍服务,无障碍服务不仅提供了一种驻留后台的方法,其本身还提供了很多普通应用无法做到的功能,比如模拟系统交互、模拟手势等。所以很多安卓App都借助无障碍服务来完成某些功能,比如就连抖音App都提供了一个无障碍服务。
这里就以微动手势为例,安装完成并打开无障碍服务,然后我分别测试以下四种情况:
每种情况下我进行四种操作测试,这四种情况都是用户常做的一些操作,然后判断微动手势的后台是否工作正常,四种操作分别如下:
测试结果,我绘制表格如下:
EMUI | MIUI | EMUI(加锁) | MIUI(加锁) | EMUI(白名单) | MIUI(白名单) | EMUI(锁+白名单) | MIUI(锁+白名单) | |
---|---|---|---|---|---|---|---|---|
锁屏 | 正常 | 冻结 | 正常 | 正常 | 正常 | 正常 | 正常 | 正常 |
一键清理 | 被杀 | 被杀 | 正常 | 正常 | 正常 | 被杀 | 正常 | 正常 |
划卡片 | 被杀 | 被杀 | 被杀 | 被杀 | 正常 | 被杀 | 正常 | 被杀 |
耗尽内存 | 正常 | 正常 | 正常 | 正常 | 正常 | 正常 | 正常 | 正常 |
我们仔细看下这里的结果,明显MIUI比EMUI的后台控制更严格,大概总结一下:
两种方式孰优孰劣,我不做评价,但显然MIUI的方式,如果想保留后台,用户在设置白名单之后,还需要加锁并小心避免划卡片。提醒一点,如果你在系统里同时为应用设置了允许自启动,那么一些后台应用在被杀之后会立刻重启,也就是杀的效果变成了重启。
这里说的定时服务是个统称,指借助安卓的某个”定时”API来实现一个定时运行的后台,安卓自己在这里也很乱,前前后后提供了AlarmManager、JobSchedule、WorkManager等很多不兼容的API来支持后台的定时任务,我这里统称为定时服务,我开发的碎片记忆就是典型的定时服务,这是一个背单词的应用,需要定时来检查卡片是否需要复习,然后自动从后台弹出。
依然按上述测试方法,结果如下:
EMUI | MIUI | EMUI(加锁) | MIUI(加锁) | EMUI(白名单) | MIUI(白名单) | EMUI(锁+白名单) | MIUI(锁+白名单) | |
---|---|---|---|---|---|---|---|---|
锁屏 | 正常 | 冻结 | 正常 | 正常 | 正常 | 正常 | 正常 | 正常 |
一键清理 | 被杀 | 被杀 | 正常 | 正常 | 被杀 | 被杀 | 正常 | 正常 |
划卡片 | 被杀 | 被杀 | 被杀 | 被杀 | 被杀 | 被杀 | 被杀 | 被杀 |
耗尽内存 | 被杀 | 被杀 | 被杀 | 正常 | 正常 | 被杀 | 正常 | 正常 |
从这个结果来看,定时服务相对无障碍服务,优先级要低一些,在某些无障碍服务仍然可以正常工作的场景下(比如划卡片和内存耗尽),定时服务就被杀了,不过这次MIUI和EMUI表现的相对一致一些。
这里有一点值得一提,安卓提供的定时机制里,有一部分是允许应用被杀后依然能被定时唤醒的,但这样的话,恶意软件显然可以利用这一点做到永生不死,所以像EMUI和MIUI这样的系统对这种定时都做了额外的限制,这里不再展开详述了。
Android的前台服务是一个术语:Foreground Service,表示用户可以感知到的后台服务,所以会在通知栏给出一个常驻通知,这是很多应用使用的后台机制,我开发的电池守护就使用了这个机制,通过这个机制,让应用可以在后台获取电量变化信息,从而对用户进行充电或拔除充电器的告警。
依然使用相同的测试方法,测试结果如下:
EMUI | MIUI | EMUI(加锁) | MIUI(加锁) | EMUI(白名单) | MIUI(白名单) | EMUI(锁+白名单) | MIUI(锁+白名单) | |
---|---|---|---|---|---|---|---|---|
锁屏 | 正常 | 正常 | 正常 | 正常 | 正常 | 正常 | 正常 | 正常 |
一键清理 | 被杀 | 被杀 | 正常 | 正常 | 正常 | 被杀 | 正常 | 正常 |
划卡片 | 被杀 | 被杀 | 被杀 | 被杀 | 正常 | 被杀 | 正常 | 被杀 |
耗尽内存 | 被杀 | 正常 | 被杀 | 正常 | 正常 | 正常 | 正常 | 正常 |
从耗尽内存的测试结果来看,前台服务的优先级级似乎介于无障碍服务和定时服务之间,并且EMUI和MIUI依然有不小的差异。
从上面的测试来看,无障碍服务、定时服务、前台服务几种服务类型之间有微妙的差异。而且MIUI和EMUI的的处理也有不少的差异,从我测试的两个版本看,MIUI更严苛一些,某些情况下EMUI不杀,MIUI会杀。对于开发者来说这是比较痛苦的事情,而对于用户来说,就更难理解这些细微的差异了。好在添加白名单和加锁之后,基本上还是能保住后台,所以这类需要后台的应用,通常只能引导用户去做这些设置。
这个测试只对比了MIUI和EMUI,我相信谷歌原生、三星以及其他厂商还是会有更多的差异,安卓的碎片化可见一斑。