【问题标题】:How to read "adb shell dumpsys alarm" output如何读取“adb shell dumpsys 警报”输出
【发布时间】:2015-02-26 12:46:21
【问题描述】:

我正在努力正确设置警报,并了解取消和重新安排警报的机制。

我发现,有一个 adb 命令可以检索设备上安排的所有警报,但我没有找到解释输出格式的文档。

我明白,我在这里问了很多解释,所以如果有人能提供关于“adb shell dumpsys alarm”的详细解释的链接,我将不胜感激。

所以,这里有问题:

  1. 待处理的报警批次:23

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

  2. 批次{4293d3a8 数量=1 开始=1369361 结束=1407261}:
      RTC #0:警报{4293d358 type 1 com.android.chrome}
        type=1 whenElapsed=1369361 when=+19s304ms window=-1 repeatInterval=0 count=0
        操作=PendingIntent{429e4500: PendingIntentRecord{429dbbc8 com.android.chrome broadcastIntent}}

    一个。什么是“num=1”、“start=1369361”和“end=1407261”?
    湾。我认为“RTC”代表 RTC 警报。
    C。 “#0”代表什么?
    d。 “类型=1”是什么意思?
    e. 'when=+19s304ms' 是否意味着警报将在 19 秒内触发?
    F。 “窗口=-1”是什么意思?
    G。 'repeatInterval=0' 是否意味着这是非重复警报?
    H。 'count=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' 是否代表包的名称,在上下文字段中被赋予待处理的意图?
    e. “行动”是指为意图而发送的行动吗?
    F。什么是'cmp'?我明白了,它是由包名和类名组成的——但是它们是从哪里获取的呢?从意图构造函数? G。为什么部分警报只有“act”或只有“cmp”?我假设没有“cmp”字段的警报用于隐式广播意图。然而,为什么会有没有'act'字段的警报?

  6. 报警统计:

    一个。这是什么?

【问题讨论】:

  • 假设您可能已经阅读了 AlarmManager 的 API 文档,我下一步可能会阅​​读一些相关的 AOSP 源代码:android.googlesource.com/platform/frameworks/base/+/…(这是奇巧,它似乎已经移动或更改了自)
  • @ChrisStratton - 如果他阅读了 AlarmManager 文档 - 他不会问一半的问题。而在 Lollipop 中,“核心服务”已被移至 core 子文件夹 - android.googlesource.com/platform/frameworks/base/+/master/…
  • @Alex P. 其他人没有给出毫无意义的建议,而是给了我一个答案,我问的六个问题中至少有一个问题可以在 API 中找到AlarmManager 的文档。这对您来说应该很容易,因为根据您的评论,那里至少有三个答案。

标签: android adb alarmmanager


【解决方案1】:

我意识到这个帖子很旧,但答案不容易找到,可能有用。我花了很多时间弄清楚这些消息的含义。

Q1:批次

Pending alarm batches: 23

警报被组织成批次。 As described in the documentation:

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

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

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

其中:

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

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,报警类型,见上面第一条
  • whenElapsed=1369361 是指系统启动后触发此警报的毫秒数(大约)
  • when=+19s304ms 表示警报将在 19 秒内触发,距离调用 dumpsys alarm 的时间为 304 毫秒。同样,+2d13h29m03s882ms 之类的值指的是未来 2 天 13 小时 29 分钟...的相对时间
  • window= 是指与批处理警报的方法有关的两个内部常量之一。 AlarmManager.WINDOW_EXACT=0 并在使用setExact()setAlarmClock() 安排警报时设置。 AlarmManager.WINDOW_HEURISTIC=-1 并在使用setInexactRepeating() 安排警报时设置。否则,该值由 API 版本确定。对于 API WINDOW_EXACT,对于 API >= 19,使用 WINDOW_HEURISTIC。 (我不得不dig into the AlarmManager.java source code 来解决这个问题。)
  • repeatInterval=900000 是警报重复的频率,例如每 900000 毫秒或 15 分钟。值 0 表示警报不重复。
  • count= 指警报应该被触发但的次数某些原因。 0 在这里是一个很好的数字。 >0 表示由于某种原因跳过了警报。
  • operation=PendingIntent{...} 是对由警报触发的PendingIntent 的引用。根据PendingIntent 是使用getServicegetBroadcastgetActivity 还是getActivities 实例化的,警报将启动服务、发送广播或启动一个或多个活动。

Q3:广播引用计数

要了解这个和之后的其他输出项,我必须dig into the AlarmManagerService.java source code

为了使某些警报起作用,设备必须被唤醒,并且在发送所有必要的广播之前不应重新进入睡眠状态。内部变量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
    ...

与:

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

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

总结

使用adb shell dumpsys alarm 的输出调试android 警报可能很棘手,并且没有完全解释dumpsys 消息的中心位置。警报如何组合在一起并不总是很明显,有时很难在需要时准确触发服务或活动。希望这对尝试调试警报的人来说是有用的参考。

【讨论】:

    【解决方案2】:

    作为一个也被闹钟困扰的人,这里有两个提示:

    调试shell输出:

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

    • 实时取消警报(在创建后)。使用取消,如果您安排了待处理的意图,则需要:alarmManager.cancel(pendingIntent)pendingIntent.cancel()

    【讨论】:

      【解决方案3】:

      尽管您只需要知道 morphatic 的答案,我还是为 GUI 创建了一个开源项目,以便以可视方式显示相同的信息。我认为它可能对其他人有用,因为它首先是对我有用的。

      https://github.com/Dottorhouse/DumpsysAlarm

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-14
        • 1970-01-01
        相关资源
        最近更新 更多