我意识到这个线程很旧,但答案不容易找到,而且可能有用。我花了很多时间来弄清楚这些消息的含义。
Q1: 批次
Pending alarm batches: 23
警报被组织成批次。如文档中所述:
从 API 19 开始,传递给此方法的触发时间被视为不精确:警报不会在此时间之前传递,但可能会推迟并稍后传递。操作系统将使用此策略以便"batch"整个系统的警报一起发出,最大限度地减少设备需要“唤醒”的次数并最大限度地减少电池的使用。一般来说,安排在不久的将来的警报不会被推迟,只要安排在很远的将来的警报。
每批次可能有多个警报。在这种情况下有 23 个batches警报,这意味着安排的警报可能远多于 23 个。在里面dumpsys alarm
输出,描述每个批次的行如下所示:
Batch{4293d3a8 num=1 start=1369361 end=1407261}:
其中:
-
4293d3a8
是与批次关联的内部 ID。
-
num=1
是该批次中的警报数量。在这种情况下,该批次中只有一个警报。
- the
start
and end
数字表示自系统上次重新启动以来经过的毫秒数这篇文章中描述的,也粗略地表示了该批次中的警报应被触发的时间窗口。
Q2:警报
每个警报由三行描述,如下所示:
RTC #0: Alarm{4293d358 type 1 com.android.chrome}
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
, or ELAPSED
,代表type
报警值,分别对应整数值0-3
-
#0
是批次内警报的编号,其中数字从 0 到n-1
where n
是批次中的警报数量。如果您的闹钟与其他闹钟一起批处理,则最远的未来时间“when=”定义时间all将触发该批次的警报。
-
4293d358
是与警报关联的内部 ID 号
-
com.android.chrome
是设置闹钟的类的包名
-
type=1
,警报类型,请参见上面的第一个项目符号
-
whenElapsed=1369361
指系统启动后多少毫秒将触发此警报(大约)
-
when=+19s304ms
表示警报将在 19 秒(304 毫秒)后触发dumpsys alarm
被称为。同样,像这样的值+2d13h29m03s882ms
指的是未来2天、13小时、29分钟……的相对时间
-
window=
指与警报批量处理方法有关的两个内部常量之一。AlarmManager.WINDOW_EXACT=0
并在闹钟被安排时设置setExact()
or setAlarmClock()
. AlarmManager.WINDOW_HEURISTIC=-1
并在闹钟被安排时设置setInexactRepeating()
。否则,该值由 API 版本确定。对于 API WINDOW_EXACT用于 API >= 19,WINDOW_HEURISTIC
用来。 (我不得不深入挖掘AlarmManager.java源代码来弄清楚这一点。)
-
repeatInterval=900000
是闹钟重复的频率,例如每 900000 毫秒或 15 分钟一次。值 0 表示警报不重复。
-
count=
指的是报警的次数should已被触发,但是wasn't因为某些原因。 0 在这里是一个很好的数字。 >0 表示由于某种原因跳过了警报。
-
operation=PendingIntent{...}
是对PendingIntent由警报触发。取决于是否PendingIntent
被实例化使用getService
, getBroadcast
, getActivity
, or getActivities
,闹钟将启动一项服务、发送广播或启动一项或多项活动。
Q3:广播引用计数
要了解此内容以及此后的其他输出项目,我必须深入挖掘AlarmManagerService.java源代码.
为了使某些警报起作用,必须唤醒设备,并且在发送所有必要的广播之前不应返回睡眠状态。内部变量mBroadcastRefCount
初始化为 0,并随着要发送的广播排队而递增。每次发送广播时,它都会递减,当它回到 0 时,wakeLock
已释放,设备可以返回睡眠状态。
Broadcast Ref Count: 0
只是意味着当时dumpsys alarm
已运行,它没有在发送任何广播。
Q4:最重要的警报
这是按警报代码运行的总时间降序排列的前十个警报。这可用于查找消耗最多系统资源的警报,例如查找可能导致电池寿命耗尽的错误进程。
Q5:警报统计
此部分显示自上次重新启动系统以来运行的所有警报的统计信息。您可以在此处查看您过去设置的闹钟是否已被触发,是否唤醒了手机等。接下来将介绍这些条目的格式。
Q6:报警统计条目
警报统计条目如下所示:
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
...
with:
警报可能同时具有cmp={...}
and a act=...
条目,意味着警报既广播意图又启动服务。
Summary
使用输出调试 android 警报adb shell dumpsys alarm
可能很棘手,并且没有中心位置dumpsys
消息已得到充分解释。警报如何批量组合在一起并不总是显而易见,有时很难在需要时准确触发服务或活动。希望这将为尝试调试警报的人们提供有用的参考。