安卓开发

安卓的后台机制既是安卓的一个优势,也是碎片化很严重的一个特性,作为三款依赖安卓后台服务的App的开发者,写下这篇文章来比较一下EMUI和MIUI这两个最常见的安卓系统的后台处理逻辑,先把要比较的系统列一下:

  • EMUI 10.0.0, Android 10
  • MIUI 12.0.6, Android 10

比较后台机制的前提是两个系统均使用缺省设置,不考虑诸如省电模式、极简模式等特殊情况,这样符合大部分用户的使用情况。

概述

常见的安卓App驻留后台方式有三种:

  • 注册系统服务,比如无障碍服务
  • 使用安卓定时服务
  • 常驻通知栏的前台服务,即Foreground Service

这三种后台模式,我都开发过相应的App,下面会分别举例来比较。除此以后,还有一些匪夷所思,也非官方认可的谋取驻留后台的方式,比如播放一个无声的音乐、开启一个单像素的悬浮窗等等,毕竟不属于正道,本文就不比较了。

在比较之前,有必要说明一下,对于现在各厂商安卓系统,比如我们要比较的EMUI和MIUI,仅仅按照这种正规方式注册服务是不够的,还是很容易被系统冻结或杀掉,原因是因为按正规方式注册服务,所有的应用都可以做到,后台多了,加上一些应用没有节制,手机就必然卡顿费电,所以厂商们的做法也很好理解,默认全杀,做一个只能手工配置的白名单,用户加入白名单才允许后台服务,这样对于大部分普通用户,不用做任何设置就免受恶意软件之苦。

需要注意,不同系统白名单配置稍有不同:

  • MIUI 设置 》应用设置 》应用管理 》选择应用 》 设置省电策略、自启动
  • EMUI 设置 》 应用 》 应用启动管理 》 选择应用 》 设置允许后台活动、自启动

下面开始测试三种后台方式。

无障碍服务

我开发的微动手势,就是一个典型的无障碍服务类应用,安卓系统支持应用注册为无障碍服务,无障碍服务不仅提供了一种驻留后台的方法,其本身还提供了很多普通应用无法做到的功能,比如模拟系统交互、模拟手势等。所以很多安卓App都借助无障碍服务来完成某些功能,比如就连抖音App都提供了一个无障碍服务。

这里就以微动手势为例,安装完成并打开无障碍服务,然后我分别测试以下四种情况:

  • 默认:就是默认安装后不做任何设置
  • 加锁:在多任务界面中给应用的卡片加锁
  • 白名单:在系统中将应用加入后台白名单
  • 锁+白名单:上面两个都设置

每种情况下我进行四种操作测试,这四种情况都是用户常做的一些操作,然后判断微动手势的后台是否工作正常,四种操作分别如下:

  • 锁屏:锁屏等一分钟后再解锁
  • 划卡片:直接在多任务页面中划去应用
  • 一键清理:在多任务页面中点一键清理
  • 耗尽内存:通过启动多个大型软件或游戏挤占剩余内存

测试结果,我绘制表格如下:

  EMUI MIUI EMUI(加锁) MIUI(加锁) EMUI(白名单) MIUI(白名单) EMUI(锁+白名单) MIUI(锁+白名单)
锁屏 正常 冻结 正常 正常 正常 正常 正常 正常
一键清理 被杀 被杀 正常 正常 正常 被杀 正常 正常
划卡片 被杀 被杀 被杀 被杀 正常 被杀 正常 被杀
耗尽内存 正常 正常 正常 正常 正常 正常 正常 正常

我们仔细看下这里的结果,明显MIUI比EMUI的后台控制更严格,大概总结一下:

  • 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,我相信谷歌原生、三星以及其他厂商还是会有更多的差异,安卓的碎片化可见一斑。