当前位置: 首页 > news >正文

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 地址

  1. 安装docker
  2. 安装battery historion
  3. 准备数据
先重置
adb shell dumpsys batterystats --resetadb shell dumpsys batterystats --enable full-wake-history导出
adb bugreport bugreport.zip
  1. 查看数据 & 分析

具体使用可自行学习。

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学习专栏

ddd

相关文章:

Android电量相关知识

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

【Java多线程】线程中几个常见的属性以及状态

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

鸿蒙OS跨进程IPC与RPC通信

一、IPC与RPC通信概述 基本概念 IPC&#xff08;Inter-Process Communication&#xff09;与RPC&#xff08;Remote Procedure Call&#xff09;用于实现跨进程通信&#xff0c;不同的是前者使用Binder驱动&#xff0c;用于设备内的跨进程通信&#xff0c;后者使用软总线驱动…...

Effective Objective-C 学习(三)

理解引用计数 Objective-C 使用引用计数来管理内存&#xff1a;每个对象都有个可以递增或递减的计数器。如果想使某个对象继续存活&#xff0c;那就递增其引用计数&#xff1a;用完了之后&#xff0c;就递减其计数。计数变为 0时&#xff0c;就可以把它销毁。 在ARC中&#xf…...

蓝桥杯备赛攻略

背景 第十五届蓝桥杯大赛快要到比赛的时间了&#xff0c;按照惯例省赛就在4月9号开赛。有很多的小伙伴都报名了这次比赛&#xff0c;也有很多的同学问我应该怎么训练&#xff0c;什么水平可以拿奖。我自己也已经参加过两届蓝桥杯大赛了&#xff0c;拿到过国赛三等奖&#xff0…...

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. 模型背景 由于可转债自身的属性较多&#xff0c;因此对其定价的难度也会加大&#xff0c;在诸多影响因素中&#xff0c;未来的股价占比最高。由于股价的不可预测性&#xff0c;导致了可转债的定价在实际交易中作用非常有限。随着可转债发行数量和规模的增大&#xff0c;越…...

【闲谈】开源软件的崛起与影响

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

【教程】Linux使用aria2c多线程满速下载

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

【漏洞复现】蓝网科技临床浏览系统信息泄露漏洞

Nx01 产品简介 蓝网科技临床浏览系统是一个专门用于医疗行业的软件系统&#xff0c;主要用于医生、护士和其他医疗专业人员在临床工作中进行信息浏览、查询和管理。 Nx02 漏洞描述 蓝网科技临床浏览系统存在信息泄露漏洞&#xff0c;攻击者可以利用该漏洞获取敏感信息。 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 组复制模式切换注意点 组复制有两种运行模式&#xff0c;一种是单主模式&#xff0c;一种是多主模式。这个模式是在整个组中设置的&#xff0c;由 group_replication_single_primary_mode 这个系统变量指定&#xff0c;而且在所有成员上必须保持一致。ON 表示单主模式&#…...

petalinux2018.3安装步骤

1、虚拟机安装ubuntu-16.04.7-desktop-amd64.iso &#xff08;注意&#xff1a;安装ubuntu-18.04.6-desktop-amd64.iso和ubuntu-16.04.6-desktop-i386.iso会报以下错误&#xff09; environment: line 314: ((: 10 #15~1 > 10 #3: syntax error in expression (error toke…...

ubuntu22.04下使用conda安装pytorch(cpu及gpu版本)

本文介绍了conda下安装cpu、gpu版本的pytorch&#xff1b;并介绍了如何设置镜像源 ubuntu环境安装pytorch的CPU版本与GPU版本 系统&#xff1a;ubuntu22.04 显卡&#xff1a;RTX 3050 依赖工具&#xff1a;miniconda 确认环境 lsb_release -a No LSB modules are available.…...

突破编程_C++_高级教程(模板编程的基础知识)

1 模板编程的基本概念 C 的模板编程是一种编程技术&#xff0c;它允许程序员编写处理不同类型数据的通用代码。通过使用模板&#xff0c;可以创建与特定数据类型无关的函数或类&#xff0c;这些函数或类在编译时可以根据需要生成特定数据类型的版本。这增加了代码的复用性、灵…...

胆小勿入!AI创作恐怖电影宣传片《生化危机:重生》

胆小勿入&#xff01;AI创作恐怖电影宣传片《生化危机&#xff1a;重生》 "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 连接进行可靠的传送。 定义了浏览器与万维网服务器通信的格式和规则。 是万维网上能够可靠地交换文件&#xff08;包括文本、声音、图像等各种多媒体文件&#xff09;的重要基础。 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初探&#xff1a;认识数据可视化与Matplotlib Fig.1 利用Matplotlib进行数据可视化( 可视化代码见文末) &#x1f335;文章目录&#x1f335; &#x1f333;引言&#x1f333;&#x1f333;一、数据可视化简介&#x1f333;&#x1f333;二、Matplotlib库简介&#x…...

LeetCode 0987.二叉树的垂序遍历:遍历时存节点信息,遍历完自定义排序

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

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…...

(一)单例模式

一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...

Linux中《基础IO》详细介绍

目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改&#xff0c;实现简单cat命令 输出信息到显示器&#xff0c;你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...