Android 电量优化

摘要:
我们强烈推荐Android开发总结文章:欢迎收藏程序员Android的推荐。Android开发人员所需的必要技能,即电源优化,一直是Android开发中的首要问题。本文将分析与Android M以上的电源优化措施相关的一些知识点。在Doze模式下,系统将定期恢复正常操作,并异步执行一些同步数据和应用程序的其他操作。当设备处于充电状态时,系统将进入标准模式,应用程序的操作不会受到限制。

Android 电量优化第1张

Android 电量优化第2张

极力推荐Android 开发大总结文章:欢迎收藏
程序员Android 力荐 ,Android 开发者需要的必备技能

Android 电量优化第3张

电量优化一直是Android 开发中的头等问题。本篇将分析一下Android M 以上电量优化措施电量优化相关的部分知识点。

注:文章参考MTK手机解决方案文档

通过本篇文章阅读,你将收获以下知识点:

1.Doze 模式
2.空闲状态下,优化app耗电
3.Doze 模式下的限制措施
4.Doze 模式概要
5.Doze 模式涉及的类如下:
6.Doze 模式状态
7.Doze 白名单
8.Doze 模式测试方法
9.开启Doze dubug 调试开关

1.Doze 模式

当设备处于非充电、灭屏状态下静止一段时间,设备将进入睡眠状态,进入Doze模式,延长电池使用时间。Doze 模式下系统会定期恢复正常操作,异步执行app的一些同步数据等操作。比如很长时间不使用,系统会允许设备一天访问一次网络等。当设备处于充电状态下,系统将进入标准模式,app执行操作将不被限制。

2.空闲状态下,优化app耗电

在用户没有使用app的情况下,系统会使app处于idle 状态,
在空闲状态下,系统将会禁止app 网络访问以及数据同步

3.Doze 模式下的限制措施

1.禁止网络访问
2.忽略Wake lock
3.忽略Alarms(setAlarmClock() 、AlarmManager.setAndAllowwhileIdle() 这两个方法除外)
4.忽略 WIFI 扫描
5.同步作业调度程序将不被执行

4.Doze 模式概要

Doze模式概要

5.Doze 模式涉及的类如下:

frameworks/base/services/core/java/com/android/server/DeviceIdleController.java

   /**
  * Keeps track of device idleness and drives low power mode based on that.
  */
   public class DeviceIdleController extends SystemService
        implements AnyMotionDetector.DeviceIdleCallback {

6. Doze 模式状态

  • ACTIVE:手机设备处于激活活动状态
  • INACTIVE:屏幕关闭进入非活动状态
  • IDLE_PENDING:每隔30分钟让App进入等待空闲预备状态
  • IDLE:空闲状态
  • IDLE_MAINTENANCE:处理挂起任务

 Doze 模式状态

对应的 Doze 模式状态如下:
Doze模式状态图

active---> inactive ---> idle_pending

运动模式检测

  void handleMotionDetectedLocked(long timeout, String type) {
        // The device is not yet active, so we want to go back to the pending idle
        // state to wait again for no motion.  Note that we only monitor for motion
        // after moving out of the inactive state, so no need to worry about that.
        boolean becomeInactive = false;
        if (mState != STATE_ACTIVE) {
            scheduleReportActiveLocked(type, Process.myUid());
            mState = STATE_ACTIVE;
            mInactiveTimeout = timeout;
            mCurIdleBudget = 0;
            mMaintenanceStartTime = 0;
            EventLogTags.writeDeviceIdle(mState, type);
            addEvent(EVENT_NORMAL);
            becomeInactive = true;
        }
        if (mLightState == LIGHT_STATE_OVERRIDE) {
            // We went out of light idle mode because we had started deep idle mode...  let's
            // now go back and reset things so we resume light idling if appropriate.
            mLightState = STATE_ACTIVE;
            EventLogTags.writeDeviceIdleLight(mLightState, type);
            becomeInactive = true;
        }
        if (becomeInactive) {
            becomeInactiveIfAppropriateLocked();
        }
    }

idle_pending ————>sensing


    @Override
    public void onAnyMotionResult(int result) {
        if (DEBUG) Slog.d(TAG, "onAnyMotionResult(" + result + ")");
        if (result != AnyMotionDetector.RESULT_UNKNOWN) {
            synchronized (this) {
                cancelSensingTimeoutAlarmLocked();
            }
        }
        if (result == AnyMotionDetector.RESULT_MOVED) {
            if (DEBUG) Slog.d(TAG, "RESULT_MOVED received.");
            synchronized (this) {
                handleMotionDetectedLocked(mConstants.INACTIVE_TIMEOUT, "sense_motion");
            }
        } else if (result == AnyMotionDetector.RESULT_STATIONARY) {
            if (DEBUG) Slog.d(TAG, "RESULT_STATIONARY received.");
            if (mState == STATE_SENSING) {
                // If we are currently sensing, it is time to move to locating.
                synchronized (this) {
                    mNotMoving = true;
                    stepIdleStateLocked("s:stationary");
                }
            } else if (mState == STATE_LOCATING) {
                // If we are currently locating, note that we are not moving and step
                // if we have located the position.
                synchronized (this) {
                    mNotMoving = true;
                    if (mLocated) {
                        stepIdleStateLocked("s:stationary");
                    }
                }
            }
        }
    }
7.Doze 白名单

电量优化白名单
设置 --电池 --电量优化(menu菜单)
会设置查看app 电池优化使用情况
白名单是以xml形式存储(deviceidle.xml)
查看白名单命令

//主要存放app包名
adb shell dumpsys deviceidle whitelist

白名单代码保存部分代码如下


    /**
     * Package names the system has white-listed to opt out of power save restrictions,
     * except for device idle mode.
     */
    private final ArrayMap<String, Integer> mPowerSaveWhitelistAppsExceptIdle = new ArrayMap<>();

    /**
     * Package names the system has white-listed to opt out of power save restrictions for
     * all modes.
     */
    private final ArrayMap<String, Integer> mPowerSaveWhitelistApps = new ArrayMap<>();

    /**
     * Package names the user has white-listed to opt out of power save restrictions.
     */
    private final ArrayMap<String, Integer> mPowerSaveWhitelistUserApps = new ArrayMap<>();

    /**
     * App IDs of built-in system apps that have been white-listed except for idle modes.
     */
    private final SparseBooleanArray mPowerSaveWhitelistSystemAppIdsExceptIdle
            = new SparseBooleanArray();

    /**
     * App IDs of built-in system apps that have been white-listed.
     */
    private final SparseBooleanArray mPowerSaveWhitelistSystemAppIds = new SparseBooleanArray();

    /**
     * App IDs that have been white-listed to opt out of power save restrictions, except
     * for device idle modes.
     */
    private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray();

    /**
     * Current app IDs that are in the complete power save white list, but shouldn't be
     * excluded from idle modes.  This array can be shared with others because it will not be
     * modified once set.
     */
    private int[] mPowerSaveWhitelistExceptIdleAppIdArray = new int[0];

    /**
     * App IDs that have been white-listed to opt out of power save restrictions.
     */
    private final SparseBooleanArray mPowerSaveWhitelistAllAppIds = new SparseBooleanArray();

    /**
     * Current app IDs that are in the complete power save white list.  This array can
     * be shared with others because it will not be modified once set.
     */
    private int[] mPowerSaveWhitelistAllAppIdArray = new int[0];

    /**
     * App IDs that have been white-listed by the user to opt out of power save restrictions.
     */
    private final SparseBooleanArray mPowerSaveWhitelistUserAppIds = new SparseBooleanArray();

    /**
     * Current app IDs that are in the user power save white list.  This array can
     * be shared with others because it will not be modified once set.
     */
    private int[] mPowerSaveWhitelistUserAppIdArray = new int[0];

8. Doze 模式测试方法

1.开启Doze
adb shell dumpsys deviceidle enable
// or MTK addadb shell setprop persist.config.AutoPowerModes 1
2.拔掉电池
adb shell dumpsys battery unplug
3.调试Doze状态

Active ---idle_pending---sensing--location---idle --idle_mantenance

adb shell dumpsys deviceidle step
4.Dump Doze 状态分析

Doze 模式下的信息,包括电池电量优化白名单等
adb shell dumpsys deviceidle

9. 开启Doze dubug 调试开关

默认false 关闭,设置为true 开启DeviceIdleController.java
private static final boolean DEBUG = false;

Android 电量优化第7张

至此,本篇已结束,如有不对的地方,欢迎您的建议与指正。同时期待您的关注,感谢您的阅读,谢谢!

微信关注公众号: 程序员Android,领福利

免责声明:文章转载自《Android 电量优化》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇【if...else】身高预测sql server 函数--rand() 生成整数的随机数下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

android基本架构

Android其本质就是在标准的Linux系统上增加了Java虚拟机Dalvik,并在Dalvik虚拟机上搭建了一个JAVA的application framework,所有的应用程序都是基于JAVA的application framework之上。Android主要应用于ARM平台,但不仅限于ARM,通过编译控制,在X86、MAC等体系结构的机器上同样可...

iOS开发关于真机—App发布证书和调试证书配置

发布证书、真机调试证书、测试证书、推送证书详细过程 更重要的是让你彻底明白为什么要这样配置证书 一:发布证书 遵旨:哪个开发者的哪台电脑要发布哪个app (这句话可以多读几遍) 通过上边的遵旨可以得出要发布app需要哪些文件,为什么配置过程中要上传或者生成那些文件,结论如下 申请开发者账号,即花费了99刀给apple的账号,这是你可以登录develo...

android网络交互之DNS优化知识整理

android网络交互之DNS优化知识整理 之前的工作中,经常会遇到DNS解析出问题导致网络交互的操作无法正常进行。 UnknownHostException 在很多的移动开发过程中,与服务端的交互的url通常是包含域名的。而在实际的网络交互的过程中,第一步就需要对域名进行dns解析。 复杂的网络环境里面,dns解析会耗费很长的时间、甚至是解析失败。这是经...

Quickcocos从安装到打包

Quick-Cocos2dx-Community 是跨平台的游戏引擎,支持时下流行的 Android 移动操作系统。本节将教大家如何在 Windows 上把已经开发好的游戏打包为 Android 上可运行的 apk 文件。 Quick-Cocos2dx-Community Android 打包分以下几个步骤: (1)安装quick cocos 3.3 (2...

iOS: 实现微信支付

一、介绍: 现在的消费越来越方便,直接带个手机用各种三方的支付平台进行支付就行,例如微信、支付宝。现在正好我所做的项目中用到了微信支付,今天就来整理一下。 二、准备: 1、去微信官方开发者平台注册开发者账号:https://open.weixin.qq.com 2、然后登陆开发平台: 3、给项目对应的Bundle ID创建应用程序(默认有登陆和分享功能,...

uniapp 下获取cid

咨询多次客服统一给的答案都是下面这种,但其实是不对的,因为我写的是app端,app 没有 document window 之类的方法。 document.addEventListener('plusready', function(){ // 页面加载时触发 var pinf = plus.push.getClientInfo();...