乐于分享
好东西不私藏

功耗_消息收不到_2_Doze和AppStandby机制

功耗_消息收不到_2_Doze和AppStandby机制

    2015 年 9 月 Android 6.0的时候doze机制诞生初期,带来一阵子社交应用消息延迟、灭屏无通知消息的问题。不过现在doze带来的消息收不到的解决方案很统一了加名单解决。

一、Doze和standby简介:

    1.doze:非充电,熄屏、手机静止一段时间后,系统会进入doze模式后限制应用使用网络; 充电,亮屏解锁,手机晃动时会退出doze

    2.standby:应用冻结后,如果是用户不可感知的后台应用,限制应用使用网络; 原生48小时standby机制:原生机制对于超过48小时未使用过的应用也会限制。其中standby的白名单会使用doze的白名单。但是一般大厂还是在这一基础上自建一个standby自己的白名单便于精细化管控

闲置时间

所属存储桶 (Bucket)

限制程度

0 - 12 小时

ACTIVE / WORKING_SET

无限制

12 - 24 小时

FREQUENT

作业/闹钟延迟

24 - 48 小时

RARE

网络受限

> 48 小时

RESTRICTED

严格限制,可能无法收通知

二、解决方案

1.Settings的Doze白名单手动设置入口:

    不过这个原生的入口很多手机都找不到了,部分手机还是可以看到桌面长按App->应用信息->电池

如果不配置白名单,新安装的应用默认是归为doze的自动管控规则,即优化选项

2.Doze机制新增白名单

    添加Doze白名单的命令:adb shell dumpsys deviceidle whitelist +com.test

机制

配置路径

配置案例

说明

影响机制

调试命令

Doze

/platform/frameworks/base/data/etc/platform.xml

【系统应用Doze白名单配置】例如App安装路径:/system/app 或 /system/priv-app 目录下

Doze\Job\AppStandby\Alarm\WakeLock\Sync

查看Doze白名单:adb shell dumpsys deviceidle添加Doze白名单:adb shell dumpsys deviceidle whitelist +com.test删除Doze白名单:adb shell dumpsys deviceidle whitelist -com.test进入Doze模式:灭屏adb shell dumpsys battery unplugadb shell dumpsys deviceidle stepStepped to deep: IDLE_PENDINGadb shell dumpsys deviceidle stepStepped to deep: SENSINGadb shell dumpsys deviceidle stepStepped to deep: LOCATINGadb shell dumpsys deviceidle stepStepped to deep: IDLE【设备处于Doze】

系统应用Doze白名单省电模式下也能豁免,一般少配置

Doze\Job\AppStandby\Alarm\WakeLock\Sync\省电机制

自定义三方应用doze名单.xml

doze_pkg_white_list

【第三方应用Doze白名单】可云配推送例如App安装路径:/data/app/实现原理:DeviceIdleController.addPowerSaveWhitelistApp

Doze\Job\AppStandby\Alarm\WakeLock\Sync

temp_pkg_white_list

Doze tempWhiteList白名单

3.普通应用不是Doze白名单怎么办?

    普通应用能做到就是提高本身进程重要度

目标场景

系统判定允许的进程状态

第三方应用可做的“提权”行为(接口 / 方式)

对应 capability / 效果

Idle / Doze / Power Save Mode 下仍保活 & 联网

procState ≤ FOREGROUND_THRESHOLD_STATE

启动前台 Service(Foreground Service)

startForegroundService()+ 显示通知

提升到 FGS,不被 idle 限制

(capability & POWER_RESTRICTED_NETWORK) != 0

申请 REQUEST_IGNORE_BATTERY_OPTIMIZATIONS

PowerManager.isIgnoringBatteryOptimizations()

获得 POWER_RESTRICTED_NETWORK 能力

Low Power Standby(LPS)下仍运行

procState ≤ TOP_THRESHOLD_STATE

成为 TOP 应用(前台 Activity)

用户正在操作的界面

唯一合法方式

 第三方无法绕过不能在 LPS 下后台运行系统强制限制

后台仍允许网络访问

procState < BACKGROUND_THRESHOLD_STATE

短时任务 / 前台 Service

避免落入 BACKGROUND

(capability & POWER_RESTRICTED_NETWORK) != 0

加入电池白名单 / 关闭应用待机

获得后台联网能力

Restrict Background(数据节省)下仍联网

procState ≤ IMPORTANT_FOREGROUND

播放音频 / 导航 / 下载

(系统认定的 IMPORTANT_FOREGROUND)

用户感知型任务

(capability & USER_RESTRICTED_NETWORK) != 0

 用户手动授予“不受限制的后台数据”

用户侧提权

    以下是源码根据不同的进程重要度,限制后台应用的联网行为,后台应用联网行为会影响对应消息通知的接收

/** @hide */public static boolean isProcStateAllowedWhileIdleOrPowerSaveMode(        int procState, @ProcessCapability int capability) {    if (procState == PROCESS_STATE_UNKNOWN) {        return false;    }    if (NetPolicyStub.getInstance().isProcStateRestrictWhileIdleOrPowerSaveMode(uid            ,uidState.procState)) {        return false;    }    return procState <= FOREGROUND_THRESHOLD_STATE            || (capability & ActivityManager.PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK) != 0;}/** @hide */public static boolean isProcStateAllowedWhileInLowPowerStandby(@Nullable UidState uidState) {    if (uidState == null) {        return false;    }    if (NetPolicyStub.getInstance().isProcStateRestrictWhileInLowPowerStandby(uid            , uidState.procState)) {        return false;    }    return uidState.procState <= TOP_THRESHOLD_STATE;}/** * This is currently only used as an implementation detail for * {@link com.android.server.net.NetworkPolicyManagerService}. * Only put here to be together with other isProcStateAllowed* methods. * * @hide */public static boolean isProcStateAllowedNetworkWhileBackground(@Nullable UidState uidState) {    if (uidState == null) {        return false;    }    if (NetPolicyStub.getInstance().isProcStateRestrictNetworkWhileBackground(uid            ,uidState.procState)) {        return false;    }    return uidState.procState < BACKGROUND_THRESHOLD_STATE            || (uidState.capability & PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK) != 0;}/** @hide */public static boolean isProcStateAllowedWhileOnRestrictBackground(int procState,        @ProcessCapability int capabilities) {    if (procState == PROCESS_STATE_UNKNOWN) {        return false;    }    if (NetPolicyStub.getInstance().isProcStateRestrictWhileOnRestrictBackground(uid            ,uidState.procState)) {        return false;    }    return procState <= FOREGROUND_THRESHOLD_STATE            // This is meant to be a user-initiated job, and therefore gets similar network            // access to FGS.            || (procState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND                    && (capabilities                          & ActivityManager.PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK) != 0);}

相关学习资料