进程优先级
- 前台进程(Foreground process)
- 可见进程(Visible process)
- 服务进程(Service process)
- 后台进程(BackGround process)
- 空进程(Empty process)
这是一种粗略的划分,进程其实有一种具体的数值,称为oom_adj,注意:数值越大优先级越低。
进程被kill的场景
1.点击home键,使app长时间停留在后台,内存不足被kill
处理这种情况前提是你的app至少运行了一个service,然后通过startForeground()设置为前台服务,大大提高存活率。
2.大多数国产手机,进入锁屏一段时间,省电机制会kill后台进程
这种情况和上面不一样,是很多国产手机rom自带的优化,当锁屏一段时间后,即使手机内存够用,但为了省电也会释放掉一部分内存。
3.用户手动释放内存,包括手机自带清理工具和第三方app
清理内存软件会把优先级低于前台进程的所有进程放入清理列表,而当我们打开了清理软件就意味着其他app不可能处于前台。所以理论上可以kill任何app。因此这类场景唯一的处理方法就是加入手机的rom白名单。一般app的做法是,在设置界面加一个选项,提示用户自己去勾选自启动。
补充几点:
- 网上都是小米开启自启动就是加入白名单,其实不是这样的,经过实测就算勾选了自启动也会被内存优化加速清理掉,只不过进程会在半分钟后复活。
- 除了自启动,还有一个设置就是电池管理,比如小米的神隐模式,这部分和自启动不同的是,它是管理app在锁屏之后被省电机制杀死的场景。
进程唤醒
Service的后台进程被kill,可以通过service自有api来重启service。但它不是100%保证重启成功,比如下面2种情况:
- Service第一次被异常杀死后会在5s内重启,第二次被杀死会在10s内重启,第三次会在20s内重启,一旦在短时间内Service被杀死达到5次,则系统不再拉起。实测小米一般只能拉起3次,oppo稍微好一点。
- 进程被取得Root权限的管理工具或系统工具通过forestop停止掉,无法重启。
实测结果
前台服务就是手机通知栏上的通知,会一直挂在通知栏,设置了不可移除。通过对普通前台服务测试,发现和当前的蓝牙钥匙服务没有什么区别。不过蓝牙唤醒服务,在创建服务时,会自动开启一个扫描,扫描到值时会回调结果。普通前台服务
- 在App没有加入自启动时,手动杀死App,前台服务也会被杀死,通知栏上的通知消失;
- 手动杀死App可以唤起服务,如果直接释放内存,这基本上不会唤起,各厂商表现不一致,汇总如下:
- 华为手机的通知不会消失,一直显示在通知栏;
- vivo手机是通知先消失,偶尔可以唤起通知,能唤起也都比较慢;
- 小米、oppo都是通知先消失,基本上不会唤起,偶有一两次可以唤起的情况;
在App加入自启动后,手动杀死App,每个厂商表现不一致,汇总如下:
如果打开App立刻弹出通知,往往这个通知是系统唤起的通知。App自己设置弹出通知比较慢,不会立刻弹出。
一般通知都是前几次唤起比较快,后面越来越慢,两三次以后就再也唤起不了了。
小米12pro
服务onStartCommand什么都不设置,加入自启动后,杀死App,服务唤起概率不稳定,而且有越来越慢的趋势,慢到一定程度后面就不会再唤起了。
- 服务onStartCommand设置START_STICKY,表现效果和没设置差不多。
如果每次打开App先停止服务,再开启服务,杀死后唤起的概率会很高。
oppo findx2pro
蓝牙唤醒服务
经测试不加入自启动,手动杀死零跑App,连接全部中断,不会唤醒服务。
- 手动杀死App可以唤起服务,如果直接释放内存,这基本上不会唤起,华为手机除外;
- 加入自启动后,手动杀死App,每个厂商表现都不同。小米手机手动杀死App,有概率会唤醒并成功连接(只有小米有波动,其他厂商唤醒概率都比较稳定)。
- 华为手机,手动杀死后,通知栏不消失,蓝牙钥匙连接不断开。
- oppo findx2pro ,手动杀死后,蓝牙钥匙连接先断开,通知栏消失,然后弹出通知栏,再次连接上蓝牙钥匙。唤醒概率比小米好一点;
- 小米手机,手动杀死后,蓝牙钥匙连接先断开,通知栏消失,然后弹出通知栏,再次连接上蓝牙钥匙。稳定性不够好,有概率唤醒;
- vivo x70pr手机,手动杀死后,蓝牙钥匙连接先断开,通知栏消失,然后弹出通知栏,再次连接上蓝牙钥匙。唤醒概率比较稳定;
- 必须要开启蓝牙,允许通知,这个通知才能弹出;
- 当周围没有广播时,调用一次bluetoothAdapter.getBluetoothLeScanner().startScan(scanFilterList, settings, callbackIntent)无法弹出通知,再调用一次可以弹出通知;
- 当周围没有广播时,调用一次startScan,不会弹出通知。当进入有广播时,立刻弹出通知,并返回扫描结果;
- 当周围有广播时,调用一次startScan,立刻弹出通知,并返回扫描结果;
- 加入自启动后,手动杀死App,通知弹出后,周围有广播时,只会扫描一次;
- 小米手机加入自启动,手动杀死App,前面2~3次可以重新拉起服务,后面无论周围有没有广播都很难拉起;
- Oppo手机和小米类似,不过比小米要好一点,周围有广播时拉起服务概率高,没有广播时,当再次开启广播,有概率可以拉起;