Android 9(API 级别 28)引入了一些新功能来改进设备电源管理。 这些变化,连同先前版本中已经存在的功能,有助于确保将系统资源提供给最需要它们的应用。
电源管理功能可以分为两个类别:
- 应用待机群组
- 系统将根据用户的使用模式限制应用对 CPU 或电池等设备资源的访问。 这是 Android 9 中新增的一项功能。
- 省电模式改进
- 开启省电模式后,系统会对所有应用施加限制。 这是一项已有的功能,但在 Android 9 中得到了改进。
注:这些变化适用于所有应用,无论它们是否以 Android 9 为目标。
应用待机群组
Android 9 引入了一项新的电池管理功能,即应用待机群组。 应用待机群组可以基于应用最近使用时间和使用频率,帮助系统排定应用请求资源的优先级。 根据使用模式,每个应用都会归类到五个优先级群组之一中。 系统将根据应用所属的群组限制每个应用可以访问的设备资源。
五个群组按照以下特性将应用分组:
- 活跃
如果用户当前正在使用应用,应用将被归到“活跃”群组中,例如:
- 应用已启动一个 Activity
- 应用正在运行前台服务
- 应用的同步适配器与某个前台应用使用的 content provider 关联
- 用户在应用中点击了某个通知
如果应用处于“活跃”群组,系统不会对应用的作业、报警或 FCM 消息施加任何限制。
- 工作集
如果应用经常运行,但当前未处于活跃状态,它将被归到“工作集”群组中。 例如,用户在大部分时间都启动的某个社交媒体应用可能就属于“工作集”群组。 如果应用被间接使用,它们也会被升级到“工作集”群组中 。
如果应用处于“工作集”群组,系统会对它运行作业和触发报警的能力施加轻度限制。 如需了解详细信息,请参阅电源管理限制。
- 常用
如果应用会定期使用,但不是每天都必须使用,它将被归到“常用”群组中。 例如,用户在健身房运行的某个锻炼跟踪应用可能就属于“常用”群组。
如果应用处于“常用”群组,系统将对它运行作业和触发报警的能力施加较强的限制,也会对高优先级 FCM 消息的数量设定限制。 如需了解详细信息,请参阅电源管理限制。
- 极少使用
如果应用不经常使用,那么它属于“极少使用”群组。 例如,用户仅在入住酒店期间运行的酒店应用就可能属于“极少使用”群组。
如果应用处于“极少使用”群组,系统将对它运行作业、触发警报和接收高优先级 FCM 消息的能力施加严格限制。系统还会限制应用连接到网络的能力。 如需了解详细信息,请参阅电源管理限制。
- 从未使用
- 安装但是从未运行过的应用会被归到“从未使用”群组中。 系统会对这些应用施加极强的限制。
系统会动态地将每个应用归类到某个优先级群组,并根据需要重新归类。 系统可能会依靠某个使用机器学习的预加载应用确定每个应用的使用可能性,并将应用归类到合适的群组。 如果设备上不存在系统应用,系统默认将基于应用的最近使用时间对它们进行排序。 更为活跃的应用将被归类到为应用提供更高优先级的群组,从而让应用可以使用更多系统资源。 具体而言,群组决定应用运行作业的频率,应用可以触发报警的频率,以及应用可以接收高优先级 Firebase 云信息传递 (FCM) 消息的频率。 这些限制仅在设备使用电池电量时适用,如果设备正在充电,系统不会对应用施加这些限制。
每个制造商都可以设定自己的标准来归类非活跃应用。
您不应当尝试影响应用所属的群组。
相反,您应当将精力放在确保应用在所属的群组内良好运行上。
您的应用可以通过调用新函数 UsageStatsManager.getAppStandbyBucket()
查找当前属于哪个群组。
注:位于 低电耗模式白名单中的应用不适用基于应用待机群组的限制。
最佳实践
如果您的应用已遵循低电耗模式和应用待机模式的最佳实践,那么处理新的电源管理功能不应是难事。 不过,之前正常运行的一些应用行为现在可能会引起问题。
- 不要让系统处于一种不断变换应用所属群组的状态。 系统的分组方式可以变化,每个设备制造商都可以选择使用自己的算法编写分组应用。 相反,请确保您的应用无论处于哪一个分组时行为都很恰当。
- 如果应用没有启动器 Activity,那么它可能永远不会升级到“活跃”分组中。 您需要重新设计应用,使之具有此类 Activity。
- 如果应用的通知不可操作,用户与通知交互将无法触发应用向“活跃”群组的升级。 在这种情况下,您需要重新设计某些适当的通知,让它们允许用户响应。 如需了解一些指导原则,请参阅 Material Design 通知设计模式。
类似地,如果应用在收到高优先级 FCM 消息时不显示通知,那么它不会向用户提供与应用交互的机会,也不会借此升级到“活跃”群组中。 事实上,高优先级 FCM 消息的唯一预期目的是向用户推送通知,因此,这种情况永远都不应发生。 如果您在某条 FCM 消息不触发用户交互时将其错误地标记为高优先级,它可能引起其他不良后果;例如,它可能导致您的应用耗尽配额,导致真正紧急的 FCM 消息被视为一般优先级。
注:如果用户重复忽略了某个通知,系统将向用户提供未来阻止该通知的选项。 请不要为了让您的应用处于“活跃”群组而向用户滥发通知!
如果应用分为多个软件包,那么这些软件包可能处于不同的群组中,进而拥有不同的访问权限级别。 请务必对软件包被归类到各个群组的此类应用进行测试,以便确保应用行为正常。
省电模式改进
Android 9 对省电模式进行了多处改进。 设备制造商可以决定施加的确切限制。 例如,在 AOSP 构建中,系统会应用以下限制:
- 系统会更积极地将应用置于应用待机模式,而不是等待应用空闲。
- 后台执行限制适用于所有应用,无论它们的目标 API 级别如何。
- 当屏幕关闭时,位置服务可能会被停用。
- 后台应用没有网络访问权限。
此外,还有一些设备特定的其他电源优化。 如需了解详细信息,请参阅附录: 电源管理限制。
一如既往,一种比较好的做法是在省电模式激活时对您的应用进行测试。 您可以通过设备的 Settings > Battery Saver 界面手动开启省电模式。
测试和问题排查
新的电源管理功能会影响在 Android 9 设备上运行的所有应用,无论应用是否以 Android 9 为目标。务必确保您的应用在这些设备上行为正常。
务必在各种条件下测试您的应用的主要用例,以便了解电源管理功能彼此之间的交互。 您可以使用 Android 调试桥命令开关某些功能。
Android 调试桥命令
您可以使用 Android 调试桥 shell 命令测试多个电源管理功能。
如需了解使用 ADB 将设备置于低电耗模式的信息,请参阅在低电耗模式和应用待机模式下进行测试。
应用待机群组
您可以使用 ADB 为您的应用手动指定应用待机群组。 要更改应用的群组,请使用以下命令:
$ adb shell am set-standby-bucket packagename active|working_set|frequent|rare
您还可以使用该命令一次设置多个软件包:
$ adb shell am set-standby-bucket package1 bucket1 package2 bucket2...
要检查应用处于哪一个群组,请运行以下命令:
$ adb shell am get-standby-bucket [packagename]
如果您不传递 packagename 参数,命令将列出所有应用的群组。
应用还可以调用新函数 UsageStatsManager.getAppStandbyBucket()
,在运行时查找所属的群组。
省电模式
可以使用多个命令测试您的应用在低电量条件下的行为。
注:您还可以使用设备的 Settings > Battery saver 界面将设备置于省电模式。
要模拟拔下设备电源时的情形,请使用以下命令:
$ adb shell dumpsys battery unplug
要测试设备在低电量条件下的行为,请使用以下命令:
$ adb shell settings put global low_power 1
完成测试后,您可以使用以下命令撤消设备的手动设置:
$ adb shell dumpsys battery reset