如何阅读“adb shell dumpsys alarm”输出

我正在努力适当地设置闹钟,并了解取消和重新安排闹钟的机制。

我发现,有一个adb命令来检索设备上的所有警报,但我还没有find一个文档,解释输出的格式。

我明白了,我在这里要求了很多的解释,所以如果有人会给出“adb shell dumpsys alarm”的详细解释的链接,我会非常感激。

所以,这里是问题:

  1. 未决的警报批次:23

    一个。 “23”是一些当前活动的预定警报吗?

  2. 批次{4293d3a8 num = 1 start = 1369361 end = 1407261}:
    RTC#0:报警{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}}

    一个。 'num = 1','start = 1369361'和'end = 1407261'是什么?
    湾 我想,“RTC”代表RTC报警。
    C。 什么“#0”代表?
    d。 什么意思是“type = 1”?
    即 是“时= + 19s304ms”意思是在19秒内触发报警?
    F。 什么意思是“窗口= -1”?
    G。 是'repeatInterval = 0',这意味着这是不重复的警报?
    H。 是“计数= 0”,这意味着这个闹钟不被推迟,由于手机的睡眠状态?
    一世。 'operation = PendingIntent {…}'代表待处理的意图,我将假设它会被警报触发。

  3. 广播参考计数:0

    一个。 这是什么?

  4. 顶级报警:

    一个。 这是什么?

  5. + 47s271ms运行,0唤醒,2个报警:com.username.weatherinfo
    ACT = com.username.receivers.CyclicWeatherUpdater.WEATHER_UPDATE_ACTION
    CMP = {com.username.weatherinfo / com.username.receivers.CyclicWeatherUpdater}

    一个。 是“+ 47s271ms”意味着这个警报将在47秒内被触发?
    湾 什么是'0唤醒' – 警报从未被触发?
    C。 什么是“2警报”?
    d。 “com.username.weatherinfo”代表软件包的名称,在上下文字段中被赋予待定意图吗?
    即 “行为”是指意图发送的行为吗?
    F。 什么是'cmp'? 我明白,它是由包名和类名组成的 – 但是从他们的位置? 从意图构造? G。 为什么部分报警只有“行为”或只有“cmp”? 我已经假设,没有'cmp'字段的报警是用于隐含的广播意图。 然而,为什么有没有“行为”领域的警报?

  6. 警报统计:

    一个。 这是什么?

我意识到这个线程是旧的,但答案不容易find,并可能是有用的。 我花了很多时间来研究这些消息的含义。

Q1:批次

 Pending alarm batches: 23 

警报分为批次。 如文档中所述 :

从API 19开始,传递给此方法的触发时间被视为不精确:警报在此时间之前不会传递,但可能会延迟并在一段时间后传递。 操作系统将使用此策略,以便在整个系统中“批量”报警,最大限度地减less设备需要“唤醒”的次数并尽可能减less电池的使用。 一般来说,不久的将来报警就不会延期。

每批可能有多个报警。 在这种情况下,有23个批次的警报,这意味着可能有超过23个警报预定。 在dumpsys alarm输出中,描述每个批次的行如下所示:

 Batch{4293d3a8 num=1 start=1369361 end=1407261}: 

其中:

  • 4293d3a8是与该批次关联的内部标识。
  • num=1是此批次中的警报数量。 在这种情况下,批次中只有一个警报。
  • startend数字表示自本系统上次重新启动以来经过的毫秒数,也大致表示批次中的警报应触发的时间窗口。

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_WAKEUPRTCELAPSED_WAKEUPELAPSED ,表示报警的type ,分别对应一个整数值0-3
  • #0是批次内的警报编号,其中编号从0到n-1 ,其中n是批次中的警报数量。 如果你的报警与其他报警成批,未来最远的“when =”定义了批处理中所有报警将被触发的时间。
  • 4293d358是与报警关联的内部ID号码
  • com.android.chrome是设置警报的类的包名称
  • type=1 ,报警types见上面的第一个项目符号
  • whenElapsed=1369361是指系统启动时触发该警报的毫秒数(大约)
  • when=+19s304ms表示报警将在19秒内触发,从dumpsys alarm后304毫秒。 同样, +2d13h29m03s882ms这个值是指相对时间为2天,13小时,29分…
  • window=指的是两个内部常量中的一个必须与警报批处理的方法。 AlarmManager.WINDOW_EXACT=0并在使用setExact()setExact()计划警报时设置。 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是否使用getServicegetBroadcastgetActivitygetActivities实例化,警报将启动服务,发送广播或启动一个或多个活动。

Q3:广播参考计数

为了find这个和其他输出项目之后,我不得不挖掘AlarmManagerService.java源代码 。

为了使一些警报起作用,设备必须被唤醒,并且在所有必要的广播被发送之前不应该回到睡眠状态。 内部variablesmBroadcastRefCount被初始化为0,并且随着要被发送的广播被排队而增加。 当每个广播被发送时,它被递减,当它回到0时, wakeLock被释放,设备可以回到睡眠状态。

Broadcast Ref Count: 0仅仅意味着当dumpsys alarm运行时,它不在发送任何广播。

Q4:顶级报警

这是按报警代码运行总时间降序排列的前十位报警。 这可以用来查找消耗最多系统资源的警报,例如,查找可能导致电池寿命耗尽的过程。

Q5:警报统计

本节显示自系统上次重新启动以来所有已运行的警报的统计数据。 在这里,您可以查看过去设置的警报是否已触发,是否打开了电话等等。下面介绍这些条目的格式。

Q6:警报统计input

警报状态条目如下所示:

 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触发次数为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 ... 

有:

  • act=...是被广播的意图的名字

警报可能同时具有cmp={...}act=...条目,这意味着警报既广播了意图又启动了服务。

概要

使用adb shell dumpsys alarm输出来debuggingandroid adb shell dumpsys alarm可能会非常棘手,并且没有中心位置可以完全解释dumpsys消息。 警报如何组合在一起并不总是显而易见的,有时很难在需要时准确地触发服务或活动。 希望这将成为试图debugging其警报的人们的有用参考。

作为一个也闹惊讶的人,这里有两个提示:

debuggingshell输出:

  • 看到负面或巨大的时间(例如-2hr57m20s311ms,14d5hr23m07s500ms),是因为我混淆了时钟的types(例如RTC与ELAPSED)。 这在文档“ RTC_WAKEUP: Alarm time in System.currentTimeMillis() ”中很清楚RTC_WAKEUP: Alarm time in System.currentTimeMillis() https://developer.android.com/reference/android/app/AlarmManager.html#RTC_WAKEUP

  • 实时(创build后)取消警报。 使用取消,如果您计划一个挂起的意图需要两个: alarmManager.cancel(pendingIntent)pendingIntent.cancel()

即使morphatic的答案是所有你需要知道的,我已经创build了一个GUI的开源项目,以可视方式显示相同的信息。 我认为这对其他人可能是有用的,因为这对我来说是第一位的。

https://github.com/Dottorhouse/DumpsysAlarm