Android电量相关知识
关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。
专注于分享各领域原创系列文章 ,擅长java后端、移动开发、商业变现、人工智能等,希望大家多多支持。
目录
- 一、导读
- 二、概览
- 三、 查看耗电情况
- 3.1 注册广播 ACTION_BATTERY_CHANGED
- 3.2 battery historion
- 3.3 手机设置
- 3.4 命令行
- 3.5 AOP & 代理hook
- 四、优化思路
- 五、 推荐阅读
一、导读
我们继续总结学习知识,温故知新。
本文主要讲了一些电量相关知识。
二、概览
电量的消耗在线上是难以量化,目前没有很好的方式能精准的获取到线上用户电量消耗情况,所以电量测试在线下非常关键,
我们要测试重点业务耗电相关的场景,以及app处于后台时耗电量**(后台静默测试)**、app网络请求时机及请求次数。
特别是一些比价耗电的场景,如:
- Camera、Audio、Video、Bluetooth、Network、Wakelock、Sensor、Radio、Screen、WIFI、CPU、GPS
三、 查看耗电情况
模块电量(mAh) = 模块电流(mA)* 模块耗时(h)
厂商在 /frameworks/base/core/res/res/xml/power_profile.xml 文件中提供了组件的电源配置文件。
3.1 注册广播 ACTION_BATTERY_CHANGED
这种方式拿到的信息相对较少。
IntentFilter filter = new IntentFilter();filter.addAction(Intent.ACTION_BATTERY_CHANGED);Intent intent = registerReceiver(null, filter);int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
我们可以获取到电池的电量、电池状态,但这个不能反应单个app的耗电情况。
这里得到的数据都是手机整体电量,对排查耗电帮助也不到。
3.2 battery historion
可以拿到精准的电量信息及使用信息
Battery Historian 是一个工具,用于在运行 Android 5.0 Lollipop(API 级别 21)及更高版本的 Android 设备上检查电池相关信息和事件,
而设备未插入电源。它允许应用程序开发人员在时间轴上可视化系统和应用程序级事件通过平移和缩放功能,可以轻松查看自设备上次充满电以来的各种汇总统计数据,
并选择一个应用程序并检查影响所选应用程序特定电池的指标。它还允许对两个错误报告进行 A/B 比较,突出显示关键电池相关指标的差异。
github 地址
google 地址
- 安装docker
- 安装battery historion
- 准备数据
先重置
adb shell dumpsys batterystats --resetadb shell dumpsys batterystats --enable full-wake-history导出
adb bugreport bugreport.zip
- 查看数据 & 分析
具体使用可自行学习。
3.3 手机设置
在手机设置里面也可以查看耗电排行,但是只有一个总的数据,不能定位哪里耗电,没啥大作用。
3.4 命令行
adb shell dumpsys batterystats > battery.txt
batterystats 所记录的电量统计数据源自于 BatteryStatsService-电量统计服务,其实现类为 BatteryStatsImpl,内部正是使用的 PowerProfile 。
BatteryStatsImpl 为每一个应用创建与之对应的 UID 来监控器系统资源的使用情况,其统计了 12 大模块的电量消耗,如下所示:
- Camera、Audio、Video、Bluetooth、Network、Wakelock、Sensor、Radio、Screen、WIFI、CPU、GPS
在 battery.txt 搜索 ‘Estimated power use’ 关键字,可以看到大概的信息。
3.5 AOP & 代理hook
我们可以通过 aop 辅助统计耗电组件,如果耗电组件在用户的使用过程中使用过多,
那么则可以辅助断定这个用户可能出现了耗电的情况,那我们就要去了解一下情况。
我们也可以通过代理对应的 Service 实现,完成收集 Wakelock、Alarm、GPS 的申请堆栈、释放信息、手机充电状态等等。
public abstract class ProxyHook extends Hook implements InvocationHandler {/*** 要代理的真实对象* 持有的被代理对象,就是你要代理谁*/private Object proxyObj;public ProxyHook(Context context) {super(context);}public void setProxyObj(Object proxyObj) {this.proxyObj = proxyObj;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {HookedMethodHandler hookedMethodHandler = mBaseHookHandle.getHookedMethodHandler(method);if (hookedMethodHandler != null){// beforeInvoke(receiver, method, args); 方法开始// 执行方法调用Object invokeResult = hookedMethodHandler.doHookInner(proxyObj, method, args);// afterInvoke(receiver, method, args, invokeResult); 方法执行结束return invokeResult;}return method.invoke(proxyObj, args);}
}
@Overridepublic void onInstall() {Object oldObj = mContext.getSystemService(Context.ALARM_SERVICE);Class<?> clazz = oldObj.getClass();try {// 获取原始mService字段Field field = clazz.getDeclaredField("mService");field.setAccessible(true);// 返回指定对象上此 Field 表示的字段的值// IAlarmManager mService;final Object mService = field.get(oldObj);// 设置被代理对象,也可以通过构造方法传入setProxyObj(mService);// 创建代理Object proxyObject = Proxy.newProxyInstance(this.getClass().getClassLoader(), mService.getClass().getInterfaces(), this);// 将指定对象变量上此 Field 对象表示的字段设置为指定的新值。其实就是给 mService 重新赋值代理对象field.set(oldObj, proxyObject);/* 这里举个简单的例子,将用户的年龄修改为33//获取public 修饰的 指定字段名称的Field类,包含父类字段Field field = clazz.getField("age");field.set(user, 33);*/} catch (NoSuchFieldException e) {} catch (IllegalAccessException e){}}
源码下载
四、优化思路
在实际使用中,一般耗电比较多的场景有视频播放、定位、复杂运算、wakelock、网络等,
所以要避免后台长时间使用耗电组件。
同时,也可以通过 cpu profiler 查看是否处于高cpu运行状态,定位 CPU 占用率异常方法。
然后针对网络请求的优化,能使用wifi就使用wifi(用 WIFI 连接网络时的功耗要低于使用移动网络的功耗),
蜂窝移动网络下需要对请求时机及次数控制,能不请求就不请求,合理设计请求时机,禁止使用轮询,导致网络请求一直处于激活状态。
在就是定位,根据场景谨慎选择定位模式:对定位准确度没那么高的场景可以选择低精度模式,或者网络定位代替 GPS,根据业务来合理
设计请求频率,使用后要及时关闭。
用户页面上比如动画要及时关闭,后台不执行等等。
大家在具体项目中具体分析。
五、 推荐阅读
Java 专栏
SQL 专栏
数据结构与算法
Android学习专栏
相关文章:

Android电量相关知识
关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 ,擅长java后端、移动开发、商业变现、人工智能等,希望大家多多支持。 目录 一、导读二、概览三、 查看耗电情况3.1 注册广播 ACTION…...

【Java多线程】线程中几个常见的属性以及状态
目录 Thread的几个常见属性 1、Id 2、Name名称 3、State状态 4、Priority优先级 5、Daemon后台线程 6、Alive存活 Thread的几个常见属性 1、Id ID 是线程的唯一标识,由系统自动分配,不同线程不会重复。 2、Name名称 用户定义的名称。该名称在各种…...

鸿蒙OS跨进程IPC与RPC通信
一、IPC与RPC通信概述 基本概念 IPC(Inter-Process Communication)与RPC(Remote Procedure Call)用于实现跨进程通信,不同的是前者使用Binder驱动,用于设备内的跨进程通信,后者使用软总线驱动…...
Effective Objective-C 学习(三)
理解引用计数 Objective-C 使用引用计数来管理内存:每个对象都有个可以递增或递减的计数器。如果想使某个对象继续存活,那就递增其引用计数:用完了之后,就递减其计数。计数变为 0时,就可以把它销毁。 在ARC中…...
蓝桥杯备赛攻略
背景 第十五届蓝桥杯大赛快要到比赛的时间了,按照惯例省赛就在4月9号开赛。有很多的小伙伴都报名了这次比赛,也有很多的同学问我应该怎么训练,什么水平可以拿奖。我自己也已经参加过两届蓝桥杯大赛了,拿到过国赛三等奖࿰…...
react反向代理
http-proxy-middleware 使用npm安装 npm i -D http-proxy-middleware 文档 点击查看 关键代码 const { createProxyMiddleware } require(http-proxy-middleware);module.exports function(app) {app.use(/api, // api开头的地址的请求createProxyMiddleware({target: ht…...

债券专题二:可转债估值-二叉树模型
1. 模型背景 由于可转债自身的属性较多,因此对其定价的难度也会加大,在诸多影响因素中,未来的股价占比最高。由于股价的不可预测性,导致了可转债的定价在实际交易中作用非常有限。随着可转债发行数量和规模的增大,越…...

【闲谈】开源软件的崛起与影响
随着信息技术的快速发展,开源软件已经成为软件开发的趋势,并产生了深远的影响。开源软件的低成本、可协作性和透明度等特点,使得越来越多的企业和个人选择使用开源软件,促进了软件行业的繁荣。然而,在使用开源软件的过…...

【教程】Linux使用aria2c多线程满速下载
转载请注明出处:小锋学长生活大爆炸[xfxuezhang.cn] 安装aria2c: sudo apt-get install aria2多线程下载: aria2c -x 16 -s 16 <url> 比如: aria2c -x 16 -s 16 http://images.cocodataset.org/zips/test2017.zip...

【漏洞复现】蓝网科技临床浏览系统信息泄露漏洞
Nx01 产品简介 蓝网科技临床浏览系统是一个专门用于医疗行业的软件系统,主要用于医生、护士和其他医疗专业人员在临床工作中进行信息浏览、查询和管理。 Nx02 漏洞描述 蓝网科技临床浏览系统存在信息泄露漏洞,攻击者可以利用该漏洞获取敏感信息。 Nx03…...
JSON转换List<Map<String, Object>>、Map<String, Object>
废话就不说了 早上10点研究到现在 获取redis的JSON字符串 String getPalletListNew redisService.getRedis(“getPalletListNew”, abroad “” goodsLevel “” startPort “” destinationPort “” maxTon “” minTon); 转换Map<String,Object> public …...

单主模式和多主模式切换
1 组复制模式切换注意点 组复制有两种运行模式,一种是单主模式,一种是多主模式。这个模式是在整个组中设置的,由 group_replication_single_primary_mode 这个系统变量指定,而且在所有成员上必须保持一致。ON 表示单主模式&#…...

petalinux2018.3安装步骤
1、虚拟机安装ubuntu-16.04.7-desktop-amd64.iso (注意:安装ubuntu-18.04.6-desktop-amd64.iso和ubuntu-16.04.6-desktop-i386.iso会报以下错误) environment: line 314: ((: 10 #15~1 > 10 #3: syntax error in expression (error toke…...
ubuntu22.04下使用conda安装pytorch(cpu及gpu版本)
本文介绍了conda下安装cpu、gpu版本的pytorch;并介绍了如何设置镜像源 ubuntu环境安装pytorch的CPU版本与GPU版本 系统:ubuntu22.04 显卡:RTX 3050 依赖工具:miniconda 确认环境 lsb_release -a No LSB modules are available.…...
突破编程_C++_高级教程(模板编程的基础知识)
1 模板编程的基本概念 C 的模板编程是一种编程技术,它允许程序员编写处理不同类型数据的通用代码。通过使用模板,可以创建与特定数据类型无关的函数或类,这些函数或类在编译时可以根据需要生成特定数据类型的版本。这增加了代码的复用性、灵…...

胆小勿入!AI创作恐怖电影宣传片《生化危机:重生》
胆小勿入!AI创作恐怖电影宣传片《生化危机:重生》 "The city is falling, and the dead walk among us." "In the shadow of the apocalypse, the fight for survival begins." "The streets are silent, but the nightmare …...

HTTP 超文本传送协议
1 超文本传送协议 HTTP HTTP 是面向事务的 (transaction-oriented) 应用层协议。 使用 TCP 连接进行可靠的传送。 定义了浏览器与万维网服务器通信的格式和规则。 是万维网上能够可靠地交换文件(包括文本、声音、图像等各种多媒体文件)的重要基础。 H…...
MySQL导入/导出数据
MySQL导入/导出数据 文章目录 MySQL导入/导出数据一、MySQL 导入数据1、mysql 命令导入2、source 命令导入3、使用 LOAD DATA 导入数据4、使用 mysqlimport 导入数据4.1、mysqlimport的常用选项介绍 二、MySQL 导出数据1、使用 SELECT ... INTO OUTFILE 语句导出数据2、mysqldu…...

Matplotlib初探:认识数据可视化与Matplotlib
Matplotlib初探:认识数据可视化与Matplotlib Fig.1 利用Matplotlib进行数据可视化( 可视化代码见文末) 🌵文章目录🌵 🌳引言🌳🌳一、数据可视化简介🌳🌳二、Matplotlib库简介&#x…...

LeetCode 0987.二叉树的垂序遍历:遍历时存节点信息,遍历完自定义排序
【LetMeFly】987.二叉树的垂序遍历:遍历时存节点信息,遍历完自定义排序 力扣题目链接:https://leetcode.cn/problems/vertical-order-traversal-of-a-binary-tree/ 给你二叉树的根结点 root ,请你设计算法计算二叉树的 垂序遍历…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...