我知道这个帖子有些旧了,但是答案并不容易找到,可能会有用。我花了很多时间研究这些消息的含义。
问题1: 批次
Pending alarm batches: 23
警报被分成批次。
如文档所述:
从API 19开始,传递给此方法的触发时间被视为不精确:该警报将不会在此时间之前传递,但可能被延迟并在稍后的时间传递。操作系统将使用此策略,在整个系统中
“批量”地收集警报,最大程度地减少设备需要“唤醒”的次数,并最小化电池使用。通常,计划在不久的将来的警报不会像计划在遥远的将来的警报那样被推迟。
每个批次可能有多个警报。在这种情况下,有23个
批次的警报,这意味着可能安排了许多超过23个的警报。在
dumpsys alarm
输出中,描述每个批次的行如下:
Batch{4293d3a8 num=1 start=1369361 end=1407261}:
其中:
4293d3a8
是与该批次关联的内部 ID。
num=1
表示该批次中警报的数量。在这种情况下,该批次中只有一个警报。
start
和 end
数字表示自系统上次重启以来经过的毫秒数,如此帖子所述,并且大致表示应触发该批次中警报的时间窗口。
Q2:警报
每个警报由三行描述,如下所示:
RTC
type=1 whenElapsed=1369361 when=+19s304ms window=-1 repeatInterval=0 count=0
operation=PendingIntent{429e4500: PendingIntentRecord{429dbbc8 com.android.chrome broadcastIntent}}
其中:
- 第一部分,即
RTC_WAKEUP
、RTC
、ELAPSED_WAKEUP
或ELAPSED
中的一个,表示闹钟的type
,分别对应整数值0-3。
#0
是批处理中闹钟的编号,编号从0到n-1
,其中n
是批处理中闹钟的数量。如果您的闹钟与其他闹钟一起批处理,则最远的"when="定义了批处理中所有闹钟将触发的时间。
4293d358
是与闹钟关联的内部ID号码。
com.android.chrome
是设置闹钟的类的包名。
type=1
,表示闹钟类型,请参见上面的第一点。
whenElapsed=1369361
是指自系统启动以来,闹钟将在此时触发(大约)的毫秒数。
when=+19s304ms
表示闹钟将在距离调用dumpsys alarm
的时间19秒304毫秒后触发。同样,像+2d13h29m03s882ms
这样的值表示未来2天、13小时、29分钟...等相对时间。
window=
是与闹钟分组方式相关的两个内部常量之一。 AlarmManager.WINDOW_EXACT=0
,当使用setExact()
或setAlarmClock()
安排闹钟时将设置该值。 AlarmManager.WINDOW_HEURISTIC=-1
,当使用setInexactRepeating()
安排闹钟时将设置该值。否则,该值由API版本决定。对于API < 19(KitKat),使用WINDOW_EXACT
,而对于API >= 19,则使用WINDOW_HEURISTIC
。(我不得不深入研究AlarmManager.java
源代码才能弄清楚这一点。)
repeatInterval=900000
表示闹钟重复的时间间隔,例如每900000毫秒或15分钟一次。0的值意味着闹钟不重复。
count=
指的是应该触发闹钟的次数,但由于某种原因没有被触发的次数。0是一个很好的数字。>0表示闹钟由于某种原因被跳过了。
operation=PendingIntent{...}
是对由闹钟触发的PendingIntent
的引用。根据PendingIntent
是使用getService
、getBroadcast
、getActivity
还是getActivities
实例化的,闹钟将启动服务、发送广播或启动一个或多个活动。
问题3: 广播引用计数
要了解此项和其他输出项目,我必须深入研究AlarmManagerService.java
源代码。
为了使某些闹钟工作,设备必须被唤醒,并且在所有必要的广播发送完之前不应该回到睡眠状态。内部变量mBroadcastRefCount
初始化为0,并随着需要发送的广播排队而增加。每次广播发送后,它会递减,当它回到0时,wakeLock
被释放,设备可以回到睡眠状态。
Broadcast Ref Count: 0
表示在运行dumpsys alarm
时,并没有正在发送任何广播。
问题4: 顶部闹钟
这是按总累计时间排名的前十个闹钟,可用于查找消耗最多系统资源的闹钟,例如查找可能导致电池寿命缩短的进程。
问题5:警报统计
该部分显示自上次系统重启以来运行的所有警报的统计信息。您可以在这里查看过去设置的警报是否已经被触发,它们是否唤醒了手机等。下面将介绍这些条目的格式。
问题6:警报统计条目
警报统计条目的外观如下:
com.example.someapp +1s857ms running, 0 wakeups:
+1s817ms 0 wakes 83 alarms: cmp={com.example.someapp/com.example.someapp.someservice}
+40ms 0 wakes 1 alarms: cmp={com.example.someapp/com.example.someapp.someotherservice}
第一行中:
com.example.someapp
是触发闹钟的进程包名
+1s857ms running
是进程消耗的总系统时间
0 wakeups
是设备被其中一个闹钟唤醒的次数
之后每一行都是设置的一个闹钟,其中:
+1s817ms
是消耗的总系统时间
0 wakes
是设备需要唤醒的次数
83 alarms
是该闹钟已触发的次数;对于重复闹钟,这个数字通常会大于1
cmp={...}
是闹钟触发时启动的服务
或者,如果闹钟触发了广播,则条目可能如下所示:
android +4m51s566ms running, 281 wakeups:
+2m46s583ms 0 wakes 1224 alarms: act=android.intent.action.TIME_TICK
+1m25s624ms 89 wakes 89 alarms: act=android.content.syncmanager.SYNC_ALARM
+52s898ms 0 wakes 41 alarms: act=com.android.server.action.NETWORK_STATS_POLL
...
使用:
一个闹钟可以同时具有 cmp={...}
和 act=...
条目,这意味着该闹钟既广播了意图又启动了服务。
摘要
使用 adb shell dumpsys alarm
的输出来调试 Android 闹钟可能会很棘手,并且没有一个中央位置完全解释了 dumpsys
消息。有时不明显地如何将闹钟批处理在一起,有时很难在所需的时间精确触发服务或活动。希望这对于试图调试其闹钟的人们是有用的参考。