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

时间:2015-02-26 12:46:22

标签: android adb alarmmanager

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

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

我明白,我在这里要求很多解释,所以如果有人会抛出一个关于“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'?
    即'when = + 19s304ms'是否意味着警报将在19秒内触发?
    F。什么意思'window = -1'?
    G。 'repeatInterval = 0'意味着这是非重复警报吗?
    H。 “count = 0”意味着由于手机睡眠状态,此警报未被推迟吗?
    一世。 'operation = PendingIntent {...}'代表待处理的意图,我将假设将由警报触发。

  3.   

    广播参考次数:0

    一个。这是什么?

  4.   

    热门警报:

    一个。这是什么?

  5.   

    + 47s271ms正在运行,0次唤醒,2次警报:com.username.weatherinfo   
    行为= 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.   

    警报统计:

    一个。这是什么?

3 个答案:

答案 0 :(得分:148)

我意识到这个线程已经老了,但答案不容易找到,并且可能有用。我花了很多时间来研究这些信息的含义。

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是批次中的警报数。如果您的警报与其他人一起批量处理,将来最远的时候"当="定义批次中所有警报的触发时间。
  • 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< 19(KitKat),使用WINDOW_EXACT,对于API> = 19,使用WINDOW_HEURISTIC。 (我不得不dig into the AlarmManager.java source code来解决这个问题。)
  • repeatInterval=900000是警报重复的频率,例如每900000毫秒或15分钟。值为0表示警报不会重复。
  • count=指的是触发警报 的次数,但 不是 由于某种原因。这里0是一个很好的数字。 > 0表示由于某种原因跳过了警报。
  • operation=PendingIntent{...}是对警报触发的PendingIntent的引用。根据{{​​1}}是否使用PendingIntentgetServicegetBroadcastgetActivity进行实例化,闹钟将启动服务,发送广播或启动一项或多项活动。

Q3:广播参考计数

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

为了使某些警报起作用,必须唤醒设备,并且在发送所有必要的广播之前不应该回到睡眠状态。内部变量getActivities初始化为0,并在要发送的广播排队时递增。当每个广播被发送时,它会递减,当它返回0时,mBroadcastRefCount被释放,设备可以重新进入睡眠状态。

wakeLock只是意味着在Broadcast Ref Count: 0运行时,它并未发送任何广播。

问题4:热门警报

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

Q5:警报统计

此部分显示自上次重新启动系统以来运行的所有警报的统计信息。在这里,您可以查看过去设置的警报是否被触发,是否唤醒了电话等。接下来将介绍这些条目的格式。

Q6:警报统计条目

警报统计信息条目如下所示:

dumpsys alarm

第一行中的位置:

  • 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是触发警报的次数;重复警报
  • 只会是> 1
  • 83 alarms触发警报时启动的服务

或者,如果警报触发广播,则条目可能如下所示:

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=...的输出调试android警报可能很棘手,并且没有完整解释adb shell dumpsys alarm消息的中心位置。并不总是很清楚警报如何分组在一起,有时很难在需要时准确地触发服务或活动。希望这对于试图调试警报的人来说是有用的参考。

答案 1 :(得分:5)

作为一个同时遇到警报的人,这里有两个提示:

调试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()

答案 2 :(得分:1)

尽管你需要知道的是答案,但我已经为GUI创建了一个开源项目,以便以可视方式显示相同的信息。我认为它对其他人有用,因为它一开始就适合我。

https://github.com/Dottorhouse/DumpsysAlarm