Android 保活相关研究总结(包含Android各版本后台限制总结)

android Jul 10, 2019

1. 保活

保活包括两部分:

  1. 如何保证不被杀死
  2. 如何在被杀死后拉活

1.1 会被谁杀死:

  1. 用户在最近任务中杀死
  2. 系统管理中杀死
  3. 第三方应用杀
  4. 系统内存管理机制杀
  5. 自己崩溃

1.1.1 不被用户杀死:

  1. 在最近任务中隐藏

1.1.2 不被系统管理杀:

不行

1.1.3 不被第三方应用杀:

  1. 先把第三方应用杀了

1.1.4 不被内存管理机制杀死的思路就是提升进程优先级,两个做法:

  1. 1 像素 activity
  2. Notification

1.2 拉活思路:

  1. 系统广播
  2. 第三方应用广播
  3. Native 进程
  4. JobScheduler
  5. 账户同步
  6. 双进程保活
  7. 推送服务保活
  8. 空音频

进程优先级和生命周期的关系:

  1. 前台进程: onResume之后
  2. 可见进程: onPause状态,并且没有执行onStop
  3. 服务进程: 简单的startService启动的Service
  4. 后台进程: onStop 之后的进程
  5. 空进程: 缓存之用

1.3 超级权限

  1. 设备管理权限
  2. 辅助功能
  3. 白名单

2. 保活验证

做了保活和拉活,怎么验证呢

查看进程优先级:

/proc/{pid}/oom_obj

自杀验证

手动杀掉被保活的进程,查看进程活动情况

自然选择

打开应用后正常使用手机,查看活动情况

监测进程启动脚本

#!/bin/bash

date
echo "开始监听进程 $1"
echo
while(true)
do
    n=`adb shell ps|grep "$1$"|wc -l`
    if [ $n -ne 0 ]; then
        date
        echo "进程结束"
        break
    fi;
    sleep 1;
done

3. Android 各版本后台相关机制更新

3.1 Android 9.0

前台权限

针对 Android 9 或更高版本并使用前台服务的应用必须请求 FOREGROUND_SERVICE 权限。 这是普通权限,因此,系统会自动为请求权限的应用授予此权限。

应用待机群组

系统将根据用户的使用模式限制应用对 CPU 或电池等设备资源的访问

  • 活跃
  • 工作集
  • 常用
  • 极少使用
  • 从未使用

省电模式改进

  • 系统会更积极地将应用置于应用待机模式,而不是等待应用空闲。
  • 后台执行限制适用于所有应用,无论它们的目标 API 级别如何。
  • 当屏幕关闭时,位置服务可能会被停用。
  • 后台应用没有网络访问权限

低功耗模式白名单中的应用对这些限制豁免。

3.2 Android 8.0

后台 Service 限制

应用限制

前台 Service (与内存管理中前台服务的定义不同):

  • 具有可见 Activity(不管该 Activity 已启动还是已暂停)。
  • 具有前台 Service。
  • 另一个前台应用已关联到该应用(不管是通过绑定到其中一个 Service,还是通过使用其中一个内容提供程序)。 例如,如果另一个应用绑定到该应用的 Service,那么该应用处于前台:
    • IME
    • 壁纸 Service
    • 通知侦听器
    • 语音或文本 Service

-----2019-07-03---10.33.34-1

不再允许后台应用创建后台Service

Android 8.0 有一项复杂功能:系统不允许后台应用创建后台 Service。 因此,Android 8.0 引入了一种全新的方法,即 startForegroundService(),以在前台启动新 Service。 在系统创建 Service 后,应用有五秒的时间来调用该 Service 的 startForeground() 方法以显示新 Service 的用户可见通知。 如果应用在此时间限制内未调用 startForeground(),则系统将停止此 Service 并声明此应用为 ANR。

广播限制

  • 应用清单中不再能注册隐式广播
  • 清单仍能注册显式广播
  • 可使用 Context.registerReceiver 注册显式和隐式广播
  • 需要签名权限的广播不受限制

JobScheduler 仍然为这些首先的广播提供了功能上的补充。
很多隐式广播已不受这些限制,豁免列表

3.3 Android 7.0

低功耗模式优化

在6.0的基础上进行了优化,把其中的限制分为了两步进行:

  • 未插电、屏幕关闭一段时间后进入低功耗模式的第一阶段:关闭应用网络访问、推迟作业和同步
    • 这里官网上写的是插电状态,但是根据上下文以及6.0中的说明,应当是未插电状态
  • 进入低电耗模式后设备处于静止状态达到一定时间:开始实施余下的低功耗限制

移除了三项隐式广播

在应用清单静态注册这几项广播将不再有效:

  • CONNECTIVITY_ACTION
  • ACTION_NEW_VIDEO
  • ACTION_NEW_PICTURE

JobScheduler 中提供了网络相关API对CONNECTIVITY_ACTION进行补充。

3.4 Android 6.0

概述:

6.0 添加了低功耗模式和待机模式,这两个模式会对网络、同步等做出限制,会影响拉活,但是不会直接杀掉进程。

低电耗模式

如果用户拔下设备的电源插头,并在屏幕关闭后的一段时间内使其保持不活动状态,设备会进入低电耗模式,在该模式下设备会尝试让系统保持休眠状态。在该模式下,设备会定期短时间恢复正常工作,以便进行应用同步,还可让系统执行任何挂起的操作。

限制:

  • 暂停访问网络。
  • 系统将忽略 wake locks。
  • 标准 AlarmManager 闹铃(包括 setExact() 和 setWindow())推迟到下一维护时段。
    • 如果您需要设置在低电耗模式下触发的闹铃,请使用 setAndAllowWhileIdle() 或 setExactAndAllowWhileIdle()。
    • 一般情况下,使用 setAlarmClock() 设置的闹铃将继续触发 — 但系统会在这些闹铃触发之前不久退出低电耗模式。
  • 系统不执行 Wi-Fi 扫描。
  • 系统不允许运行同步适配器。
  • 系统不允许运行 JobScheduler。

如何解除限制:
加入低功耗模式白名单, 可以豁免对网络wake locks的限制

添加方式看添加低功耗白名单

应用待机模式

应用待机模式允许系统判定应用在用户未主动使用它时处于空闲状态。当用户有一段时间未触摸应用时,系统便会作出此判定。如果拔下了设备电源插头,系统会为其视为空闲的应用停用网络访问以及暂停同步和作业。

3.5 Android 5.0

添加 JobScheduler

附录

查看服务命令、优先级命令:

cat /proc/{pid}/oom_adj

查看wakelock:

adb shell dumpsys power|grep WAKE_LOCK

反编译手段:

jadx

多的书开启收费,并且定期存档并回收

进入doze模式:

https://developer.android.com/training/monitoring-device-state/doze-standby?hl=zh-cn

锁屏后5分钟内应用会被杀死:

Android O(26) 之后,app 放后台一分钟就会停止所有service:
https://www.twblogs.net/a/5bf45a47bd9eee37a0609a90/zh-cn

官方文档
-----2019-07-03---10.33.34

log 如下:

W ActivityManager: Stopping service due to app idle: u0a227 -1m4s584ms com.cnode.blockchain/c      om.ledong.lib.leto.main.LetoService

Android O 后台执行限制

https://developer.android.com/about/versions/oreo/background?hl=zh-cn

Android N 后台优化

https://developer.android.com/about/versions/oreo/background?hl=zh-cn

/* 看板娘 */