Android 耗电过多时的log分析

最新在写一个tool,用来分析Android手机耗电过多的原因。用python。 边写边记录吧。

1. 耗电过多的原因

耗电过多的原因基本可以分为两大类。其一,CPU没有睡下去。其二,CPU被频繁唤醒。当然,前提是没有插USB,并且灭屏了。 

1.1 CPU频繁唤醒的情况

在黑屏状态下,如果手机没有异常,并且后台没有类似下载apk,播放音乐等行为的话,CPU会睡下去(后文直接用深睡代替)。并且,不会过于频繁的被唤醒(唤醒也是指CPU被唤醒,不是亮屏)。如果看log时发现机台会很频繁的唤醒(几秒一次甚至更频繁),那肯定是不正常的。

一般情况下,会在唤醒时刻的log附近直接查看唤醒源,定位到是什么唤醒了机台。可能是modem还有其他一些硬件的原因,也可能是上层apk设置了一些alarm。

1.2 CPU没有睡下去

CPU没有睡下去时,一般是因为有wakelock。可能是上层apk的wakelock,也可能是kernel中的一些driver持有的wakelock。

kernel中的wakelock的一些信息可以通过cat /d/wakeup_sources查看。active_since的值特别大的,就是怀疑对象。

还有上层的wakelock,可以查看/sys/power/wake_lock节点。当屏幕亮时,这里总是有一个PowerManagerService.Display。

2. TOOL的实现

TOOL目前的想法是对logcat log和event log进行分析。

2.1 找出没有插USB的时间段

通过event log找出没有插USB(电脑USB或者adapter)的时间段,因为如果插着USB充电,情况会变得比较复杂,也不适合用来分析耗电。

event log的含义可以参考博文:http://gityuan.com/2016/05/15/event-log/

其中关于是否有插usb的判断,可以依据battery_status

2723battery_statusstatus,health,present,plugged,technology 

例如:

04-26 16:12:25.273  2875 17395 I battery_status: [4,2,1,1,Li-ion] //1,表示有用adapter充电
04-26 16:12:25.619  2875  4146 I battery_status: [2,2,1,1,Li-ion]
04-26 16:13:28.612  2875 17396 I battery_status: [3,2,1,1,Li-ion]
04-26 16:13:28.616  2875 17396 I battery_status: [3,2,1,0,Li-ion] //0,表示usb被移除
04-26 16:55:34.546  2875  2911 I battery_status: [4,2,1,1,Li-ion] //1,表示有用adapter充电,要找出的就是这两行的时间

2.2 计算每个没有插USB(none plug)的时间段的耗电

首先,需要读取电池电量。同样,从event log中读取。

2722battery_levellevel, voltage, temperature
例如:
04-26 12:34:06.584  2875  4412 I battery_level: [65,3945,357]  //第一个值就是电量。当前电量为65%
04-26 12:43:52.743  2875 17395 I battery_level: [64,3925,352]
04-26 12:50:53.867  2875 31204 I battery_level: [63,3920,355]

对于一段没有插usb的时间段(t1,t2),需要找到t1之后第一个电量信息的时间点t11,还有找到t2之前最后一个电量信息的时间点t22,然后计算t11,t22之间的耗电是否满足要求。不过实际实现的过程中有些特殊情况,包括这一段时间内都没有电量信息、只有一个电量信息的情况,这样也只能先粗略处理,认为没有电量信息,后续不再分析这段时间。

2.3 找出耗电多的none plug时间段中screen off时间段再分析

前面已经找出来需要进一步分析的none plug时间段。那接下来就是对这个时间段分析。

首先,读取screen的信息。还是从event log中读取。

04-26 13:24:59.173  2875  2875 I screen_toggled: 1  //到锁屏界面
04-26 13:24:59.398  2875  2957 I screen_toggled: 1 
04-26 13:24:59.401  3610  3610 I screen_toggled: 2  //解锁之后界面
04-26 13:25:07.070  2875  2875 I screen_toggled: 0  //灭屏
04-26 13:29:30.780  2875  2875 I screen_toggled: 1  //重新亮屏到锁屏界面,要找出的就是上面一行到这行的时间段
04-26 13:29:30.884  2875  2957 I screen_toggled: 1

找出了一个一个的黑屏时间段,接下来需要分别黑屏时间段分析CPU睡眠情况。后面只会写一个黑屏时间段。

2.4 判断黑屏时间段内有没有深睡

深睡的log可以在logcat Log中查找。标志性log如下:

04-26 13:48:57.706  2958  2958 W KERNEL  : [149941.121406] (CPU:0-pid:2958:system_server)Suspending console(s) (use no_console_suspend to debug)

如果在黑屏时间段内都没有睡下去,并且这个时间够长,那是要看为什么没有睡下去的,也就是看wakelock。

如果在黑屏时间段内有睡下去,那后面耗电多基本是唤醒过于频繁了。 后面再看唤醒源。

2.5 对频繁唤醒的黑屏时间段查找唤醒源

目前的想法是,唤醒源还是从logcat log中的kernel log中直接读取。

另外,dumpsys batterystats中的到的+wake_reason是读取的节点:/sys/kernel/wakeup_reasons/last_resume_reason.

2.6 找出导致不能深睡的wakelock

按理说,应该读取/d/wakeup_sources来看各个wakelock的情况。但是考虑到这个节点只有root权限才能读到。只好直接读取dumpsys batterystats中的kernel wakelock信息。这个信息中主要包含从reset以来上锁的次数和时间。后面会专门写一篇文来分析wakelock.

展开阅读全文

没有更多推荐了,返回首页