- 电源管理
- 背景介绍
- 应用待机群组
- 背景介绍
Android 9 引入了一项新的电池管理功能,即应用待机群组。 应用待机群组可以基于应用最近使用时间和使用频率,帮助系统排定应用请求资源的优先级。 根据使用模式,每个应用都会归类到五个优先级群组之一中。系统将根据应用所属的群组限制每个应用可以访问的设备资源。
-
-
-
- 五个群组按照以下特性将应用分组:
-
-
分组 |
分组说明 |
活跃 |
如果用户当前正在使用应用,应用将被归到“活跃”群组中,例如:
如果应用处于“活跃”群组,系统不会对应用的作业、报警或 FCM 消息施加任何限制。 |
工作集 |
如果应用经常运行,但当前未处于活跃状态,它将被归到“工作集”群组中。 例如,用户在大部分时间都启动的某个社交媒体应用可能就属于“工作集”群组。 如果应用被间接使用,它们也会被升级到“工作集”群组中 。 如果应用处于“工作集”群组,系统会对它运行作业和触发报警的能力施加轻度限制。 |
常用 |
如果应用会定期使用,但不是每天都必须使用,它将被归到“常用”群组中。 例如,用户在健身房运行的某个锻炼跟踪应用可能就属于“常用”群组。 如果应用处于“常用”群组,系统将对它运行作业和触发报警的能力施加较强的限制,也会对高优先级 FCM 消息的数量设定限制。 |
极少使用 |
如果应用不经常使用,那么它属于“极少使用”群组。 例如,用户仅在入住酒店期间运行的酒店应用就可能属于“极少使用”群组。 如果应用处于“极少使用”群组,系统将对它运行作业、触发警报和接收高优先级 FCM 消息的能力施加严格限制。系统还会限制应用连接到网络的能力。 |
从未使用 |
安装但是从未运行过的应用会被归到“从未使用”群组中。 系统会对这些应用施加极强的限制。 |
-
-
-
- 分类规则:
-
-
- 系统会动态地将每个应用归类到某个优先级群组,并根据需要重新归类。 系统可能会依靠某个使用机器学习的预加载应用确定每个应用的使用可能性,并将应用归类到合适的群组。 如果设备上不存在系统应用,系统默认将基于应用的最近使用时间对它们进行排序。 更为活跃的应用将被归类到为应用提供更高优先级的群组,从而让应用可以使用更多系统资源。 具体而言,群组决定应用运行作业的频率,应用可以触发报警的频率,以及应用可以接收高优先级 Firebase 云信息传递 (FCM) 消息的频率。 这些限制仅在设备使用电池电量时适用,如果设备正在充电,系统不会对应用施加这些限制。
- 每个制造商都可以设定自己的标准来归类非活跃应用。
-
-
- 具体分类管控规则:
-
-
分组 |
Jobs管控 |
Alarm管控 |
Network管控 |
Push消息管控 |
活跃 |
不限制 |
不限制 |
不限制 |
不限制 |
工作集 |
推迟最多2个小时 |
推迟最多6分钟 |
不限制 |
不限制 |
常用 |
推迟最多8个小时 |
推迟最多30分钟 |
不限制 |
10次/天 |
极少使用 |
推迟最多24个小时 |
推迟最多2分钟 |
推迟最多24个小时 |
5次/天 |
-
-
- 省电模式改进
-
Android 9 对省电模式进行了多处改进。 设备制造商可以决定施加的确切限制。 例如,在 AOSP 构建中,系统会应用以下限制:
- 系统会更积极地将应用置于应用待机模式,而不是等待应用空闲。
- 后台执行限制适用于所有应用,无论它们的目标 API 级别如何。
- 当屏幕关闭时,位置服务可能会被停用。
- 后台应用没有网络访问权限。
-
-
- P版本新增FAS管控
-
用户设置限制后台活动之后的限制:
-
-
-
- 应用退后台,1分钟就会被停止Service(包括正在执行的前台任务,前台服务)
- 限制访问网络
- 限制Alarm触发
- 限制JobScheduler执行
-
-
-
-
- 后台执行限制(非P特性)
-
谷歌海外TargetSdkVersion策略要求,应用必须升级TargetSdkVersion到26+才允许上架google play,所以后台执行限制这个针对TargetSdkVersion>=26生效的功耗管控特性需要应用在P版本手机重点关注:
https://developer.android.com/about/versions/oreo/background。
-
-
-
- 后台执行限制管控内容:
-
-
- TargetSdkVersion>=26的应用将受到后台服务管控:应用处于前台时,可以自由创建和运行前台服务与后台服务。 进入后台时,在一个持续数分钟的时间窗内,应用仍可以创建和使用服务。在该时间窗结束后,应用将被视为处于 空闲 (idle)状态。 此时,系统将停止应用的后台服务,就像应用已经调用服务的“Service.stopSelf()”方法,另外应用处于空闲(idle)状态将不再允许应用再启动服,可以参考下面的日志:
08-25 14:13:23.377 1482 17299 W ActivityManager: Background start not allowed: service Intent {…
08-25 14:13:24.246 1482 3255 W ActivityManager: Service.startForeground() not allowed due to bg restriction:
- TargetSdkVersion>=26的应用将受到广播管控:应用无法收到通过静态注册的隐式广播,动态注册方式不受影响,显示广播不受影响
-
-
- 判断应用是否处于前台的条件:
-
-
- 具有可见 Activity(不管该 Activity 已启动还是已暂停)。
- 具有前台服务。
- 另一个前台应用已关联到该应用(不管是通过绑定到其中一个服务,还是通过使用其中一个内容提供程序)。 例如,如果另一个应用绑定到该应用的服务,那么该应用处于前台:
- IME
- 壁纸服务
- 通知侦听器
- 语音或文本服务
-
- 应用待机模式(非P特性)
-
应用待机模式允许系统判定应用在用户未主动使用它时处于空闲状态(idle)。当用户有一段时间未触摸应用时,系统便会作出此判定。如果拔下了设备电源插头,系统会为其视为空闲的应用停用网络访问以及暂停同步和作业。
-
-
- 低电耗模式(非P特性)
-
我们在P版本测试发现还是有很多应用没有适配谷歌的低电耗模式,导致手机进入低电耗模式之后,应用的某些后台功能受到影响,比如后台下载、播放音乐和收消息等等,并且P版本进入低电耗模式的时间由原来的15分钟缩短到5分钟,没有适配的应用更容易出现问题。
参考链接:https://developer.android.com/training/monitoring-device-state/doze-standby
-
-
-
-
- 进入低电耗模式条件:用户设备未插接电源、处于静止状态一段时间且屏幕关闭,设备会进入低电耗模式,O版本进入低电耗模式时间是15分钟左右,P版本减少到5分钟左右;
- 低电耗模式限制:
-
-
-
|
|
标准 AlarmManager 闹铃(包括 setExact() 和 setWindow())推迟到下一维护时段。 |
系统不执行 Wi-Fi 扫描 |
|
系统不允许运行 JobScheduler。 |
-
- 兼容性影响
除了后台执行限制管控是对TargetSdkVersion>=26生效以外,上面介绍的其他变化适用于所有应用,无论它们是否以 Android 9 为目标。
-
-
- 具体影响
-
影响应用后台活动包括:应用后台下载、播放音乐,收消息等等功能
-
- 适配指导
- 前台服务
- 适配指导
应用如果拥有前台服务的话,可以豁免低电耗、应用待机群组以及O版本新增的后台执行限制一系列功耗方案的管控,但是在P版本如果用户开启了应用的后台限制,有前台服务的应用也是会受到影响的:
在 Android 8.0 之前,创建前台服务的方式通常是先创建一个后台服务,然后将该服务推到前台。Android 8.0 有一项复杂功能;系统不允许后台应用创建后台服务。 因此,Android 8.0 引入了一种全新的方法,即 Context.startForegroundService(),以在前台启动新服务。在系统创建服务后,应用有五秒的时间来调用该服务的 startForeground() 方法以显示新服务的用户可见通知。如果应用在此时间限制内未调用startForeground(),则系统将停止服务并声明此应用为 ANR。
-
-
- Doze白名单
-
通过Doze白名单豁免所有的功耗方案管控:
-
-
-
- 加入doze白名单:
-
-
用户可以在 Settings > Battery > Battery Optimization 中手动配置该白名单。或者,系统会为应用提供请求用户将应用加入白名单的方式。
- 应用可以触发 ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS Intent,让用户直接进入 Battery Optimization,他们可以在其中添加应用。
- 具有 REQUEST_IGNORE_BATTERY_OPTIMIZATIONS 权限的应用可以触发系统对话框,让用户无需转到“设置”即可直接将应用添加到白名单。应用将通过触发 ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS Intent 来触发该对话框。
- 用户可以根据需要手动从白名单中移除应用。
-
-
- 用户授权加入doze白名单参考实现代码:
-
-
- 申请使用权限:
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
- 弹出用户授权对话框代码:
/**
* 忽略电池优化
*/
public void ignoreBatteryOptimization(Activity activity) {
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
boolean hasIgnored = powerManager.isIgnoringBatteryOptimizations(activity.getPackageName());
// 判断当前APP是否有加入电池优化的白名单,如果没有,弹出加入电池优化的白名单的设置对话框。
if (!hasIgnored) {
Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + activity.getPackageName()));
startActivity(intent);
}
}
-
-
- 功耗调试命令,多多测试验证
- Doze调试
- 功耗调试命令,多多测试验证
-
-
-
-
- 查看服务是否是前台服务
-
-
adb shell dumpsys activity processes 应用包名
-
-
-
- 应用待机群组调试
-
-
https://developer.android.com/about/versions/pie/power#adb-commands