前言

本章主要讲解下『电量』如何优化;
Doze 低电耗模式
低电耗模式针对的是『系统』行为;
如果设备未充电,屏幕熄灭,让设备在一段时间内保持不活动状态,设备就会处于 doze 模式,从而延迟应用的后台 CPU 和网络活动,从而降低耗电量;
在低电耗模式下,系统有些功能是不可用的;
- 暂停网络访问;
- 系统忽略 PowerManager.WakeLock 唤醒锁定【Wakelock 可以唤醒设备CPU,也就是说设备CPU不会被唤醒了,也可以唤醒屏幕,保持屏幕长亮】;
- AlarmManager 闹钟推迟到下一个维护期;
- 如果需要设置在设备处于低电耗模式时触发的闹钟,请使用 API 23(6.0) 提供的 setAndAllowWhileIdle() (一次性闹钟,同set方法)或 setExactAndAllowWhileIdle() (比set方法设置的精度更高,同setExact)
- 使用 setAlarmClock() 设置的闹钟将继续正常触发,系统会在这些闹钟触发之前不久退出低电耗模式
- 系统不执行 WLAN 扫描;
- 系统不允许运行同步适配器AbstractThreadedSyncAdapter (账号同步拉活);
- 系统不允许运行 JobScheduler;
StandBy 待机模式
待机模式针对的是『应用』行为;
当用户在一段时间内未触摸应用,并且应用没有以下表现的时候,Android 系统就会使应用进入 Stand By 模式;
但是以下几种情况除外,不会使应用进入待机模式
- 用户明确应用启动;
- 应用当前有一个进程在前台运行;
- 应用生成用户可在锁定屏幕或通知栏中看到的通知;
- 当用户将设备插入电源时,系统会从待机状态释放应用;
如何让应用跳出待机模式
- 延迟用户近期未与之交互的应用的后台网络活动
- 获取充电状态,进行业务的处理,来降低耗电量;
- 应用加入白名单
- 跳转系统设置页面,让用户自行选择加入 startActivity(new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS));
- 弹出对话框,让用户选择 还是 拒绝 Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); intent.setData(Uri.parse("package:"+getPackageName())); startActivity(intent);

WorkManager
一个针对原有的 Android 后台调度 API 整合的组件; 当应用进入后台之后,帮助我们更简单的完成一些约束条件的工作;

如何使用
约束条件 + 后台任务

App 层面电量监控
Java Hook
可以从 WakeLock,Alarm、GPS、Sensor 等角度来实现电量的监控
WakeLock
WakeLock 用来阻止 CPU、屏幕甚至是键盘的休眠,保证任务在灭屏的时候可以被正确执行,可以让应用有控制AP是否休眠。类似 Alarm、JobService 也会申请 WakeLock 来完成后台 CPU 操作。WakeLock 的核心控制代码都在 PowerManagerService 中,实现的方法非常简单;
如何使用:
ini
PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WeakLock weakLock = powerManager.newWeakLock(ON_AFTER_RELEASE | PARTIAL_WEAK_LOCK, "Tag");
// onResume 中获取
weakLock.acquire();
// onPause 中释放
weakLock.release();
然后,我们来执行 adb 命令抓取相关信息
arduino
adb shell dumpsys "power | grep -i wake"
这个 adb 命令可以用来抓取一些电量信息;

借助这些信息,通过 battry historian 可以查看申请了几次,如果申请的特别频繁,那么就会耗电的问题;
Hook 逻辑 动态代理获取两个接口的调用,用来实现电量的监控
Alarm
Alarm 用来做一些定时的重复任务,它一共有四个类型,其中 ELAPSED_REALTIME_WAKEUP 和 RTC_WAKEUP 类型都会唤醒设备。同样,Alarm 的核心控制逻辑都在 AlarmManagerService 中;
同样也是通过 动态代理 的方式来实现 hook 逻辑

插桩
基础类中 进行插桩处理
Facebook 也有一个耗电监控的开源库 Battery-Metrics
耗电检测 Battery Historian
如何进行耗电检测,我们来深度探讨下~
Battery Historian 是一个可以了解设备随时间的耗电情况的工具 。在系统级别,该工具以 HTML 的形式可视化来自系统日志的电源相关事件。在具体应用级别,该工具可提供各种数据,帮助您识别耗电的应用行为;
安装教程
安装教程,这里可以直接看这个安装教程链接 电量优化Battery Historian2.0 配置
数据收集
- 第一步:重置电池数据收集
adb shell dumpsys batterystats --reset
- 开启wakeLock唤醒锁信息记录(可选)
adb shell dumpsys batterystats --enable full-wake-history
- 断开设备与计算机的连接,以便仅消耗设备电池的电量 (注意:这个过程最少持续一个小时的时间);
- 使用您的应用并执行您想要获取数据的操作;例如,断开 WLAN 连接并将数据发送到云端
- 重新连接手机;
- 生成报告
- 对于搭载 Android 7.0 及更高版本的设备
adb bugreport > [path/]bugreport.zip
- 对于搭载 Android 6.0 及更低版本的设备
adb bugreport > [path/]bugreport.txt
- 对于搭载 Android 7.0 及更高版本的设备
- 关闭wakeLock统计:
adb shell dumpsys batterystats --disable full-wake-history
启动 Battery Historian

启动起来之后,就是这样的一个界面,然后将我们上面收集的日志信息上传给 Battry Historian;
上传成功之后,会出现下面这样的一个界面;

图中的黑线就代表着我们的一个耗电情况;
查看具体应用的数据
表格提供了关于您的应用的两个数据维度。首先,您可以查找应用的耗电量与其他应用相比的排名位置。为此,请 点击"Tables"下的"Device Power Estimates"表格。

根据耗电排名具体问题,具体分析即可;
好了,电量优化就写到这里吧
欢迎三连
来都来了,点个关注,点个赞吧,你的支持是我最大的动力~