进程优先级

  1. 前台进程(Foreground process)
  2. 可见进程(Visible process)
  3. 服务进程(Service process)
  4. 后台进程(BackGround process)
  5. 空进程(Empty process)

这是一种粗略的划分,进程其实有一种具体的数值,称为oom_adj,注意:数值越大优先级越低。

进程被kill的场景

1.点击home键,使app长时间停留在后台,内存不足被kill

处理这种情况前提是你的app至少运行了一个service,然后通过startForeground()设置为前台服务,大大提高存活率。

2.大多数国产手机,进入锁屏一段时间,省电机制会kill后台进程

这种情况和上面不一样,是很多国产手机rom自带的优化,当锁屏一段时间后,即使手机内存够用,但为了省电也会释放掉一部分内存。

3.用户手动释放内存,包括手机自带清理工具和第三方app

清理内存软件会把优先级低于前台进程的所有进程放入清理列表,而当我们打开了清理软件就意味着其他app不可能处于前台。所以理论上可以kill任何app。因此这类场景唯一的处理方法就是加入手机的rom白名单。一般app的做法是,在设置界面加一个选项,提示用户自己去勾选自启动。
补充几点:

  1. 网上都是小米开启自启动就是加入白名单,其实不是这样的,经过实测就算勾选了自启动也会被内存优化加速清理掉,只不过进程会在半分钟后复活。
  2. 除了自启动,还有一个设置就是电池管理,比如小米的神隐模式,这部分和自启动不同的是,它是管理app在锁屏之后被省电机制杀死的场景。

    进程唤醒

    Service的后台进程被kill,可以通过service自有api来重启service。但它不是100%保证重启成功,比如下面2种情况:
  • Service第一次被异常杀死后会在5s内重启,第二次被杀死会在10s内重启,第三次会在20s内重启,一旦在短时间内Service被杀死达到5次,则系统不再拉起。实测小米一般只能拉起3次,oppo稍微好一点。
  • 进程被取得Root权限的管理工具或系统工具通过forestop停止掉,无法重启。

    实测结果

    前台服务就是手机通知栏上的通知,会一直挂在通知栏,设置了不可移除。通过对普通前台服务测试,发现和当前的蓝牙钥匙服务没有什么区别。不过蓝牙唤醒服务,在创建服务时,会自动开启一个扫描,扫描到值时会回调结果。

    普通前台服务

  1. 在App没有加入自启动时,手动杀死App,前台服务也会被杀死,通知栏上的通知消失;
  2. 手动杀死App可以唤起服务,如果直接释放内存,这基本上不会唤起,各厂商表现不一致,汇总如下:
    1. 华为手机的通知不会消失,一直显示在通知栏;
    2. vivo手机是通知先消失,偶尔可以唤起通知,能唤起也都比较慢;
    3. 小米、oppo都是通知先消失,基本上不会唤起,偶有一两次可以唤起的情况;
  3. 在App加入自启动后,手动杀死App,每个厂商表现不一致,汇总如下:

    1. 小米,oppo都是通知先消失,然后再弹出在通知栏上,弹出不稳定,概率不高;
    2. 华为手机的通知不会消失,一直显示在通知栏;
    3. vivo是通知先消失,然后再弹出在通知栏上,弹出概率比较高,很稳定;

      小米和OPPO详细测试

  4. 如果打开App立刻弹出通知,往往这个通知是系统唤起的通知。App自己设置弹出通知比较慢,不会立刻弹出。

  5. 一般通知都是前几次唤起比较快,后面越来越慢,两三次以后就再也唤起不了了。

    小米12pro
  6. 服务onStartCommand什么都不设置,加入自启动后,杀死App,服务唤起概率不稳定,而且有越来越慢的趋势,慢到一定程度后面就不会再唤起了。

  7. 服务onStartCommand设置START_STICKY,表现效果和没设置差不多。
  8. 如果每次打开App先停止服务,再开启服务,杀死后唤起的概率会很高。

    oppo findx2pro

    表现和小米很像,也是唤起越来越慢,最后就唤起不来了。

    蓝牙唤醒服务

  9. 经测试不加入自启动,手动杀死零跑App,连接全部中断,不会唤醒服务。

  10. 手动杀死App可以唤起服务,如果直接释放内存,这基本上不会唤起,华为手机除外;
  11. 加入自启动后,手动杀死App,每个厂商表现都不同。小米手机手动杀死App,有概率会唤醒并成功连接(只有小米有波动,其他厂商唤醒概率都比较稳定)。
    1. 华为手机,手动杀死后,通知栏不消失,蓝牙钥匙连接不断开。
    2. oppo findx2pro ,手动杀死后,蓝牙钥匙连接先断开,通知栏消失,然后弹出通知栏,再次连接上蓝牙钥匙。唤醒概率比小米好一点;
    3. 小米手机,手动杀死后,蓝牙钥匙连接先断开,通知栏消失,然后弹出通知栏,再次连接上蓝牙钥匙。稳定性不够好,有概率唤醒;
    4. vivo x70pr手机,手动杀死后,蓝牙钥匙连接先断开,通知栏消失,然后弹出通知栏,再次连接上蓝牙钥匙。唤醒概率比较稳定;
  12. 必须要开启蓝牙,允许通知,这个通知才能弹出;
  13. 当周围没有广播时,调用一次bluetoothAdapter.getBluetoothLeScanner().startScan(scanFilterList, settings, callbackIntent)无法弹出通知,再调用一次可以弹出通知;
  14. 当周围没有广播时,调用一次startScan,不会弹出通知。当进入有广播时,立刻弹出通知,并返回扫描结果;
  15. 当周围有广播时,调用一次startScan,立刻弹出通知,并返回扫描结果;
  16. 加入自启动后,手动杀死App,通知弹出后,周围有广播时,只会扫描一次;
  17. 小米手机加入自启动,手动杀死App,前面2~3次可以重新拉起服务,后面无论周围有没有广播都很难拉起;
  18. Oppo手机和小米类似,不过比小米要好一点,周围有广播时拉起服务概率高,没有广播时,当再次开启广播,有概率可以拉起;