如何读取“ adb 外壳垃圾报警器”的输出

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

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

我明白,我在这里要求很多解释,所以如果任何人能提供一个链接,详细解释“ adb shell Dumpsy 闹钟”,我会非常感激。

所以,问题是这样的:

  1. 待定警报批次: 23

    “23”是一些当前正在使用的、预定的警报吗?

  2. 批号{4293d3a8 num = 1 start = 1369361 end = 1407261} :
    RTC # 0: 警报{4293d358 type 1 com.android.chrome }
    Type = 1 when Elapsed = 1369361 when = + 19 s304ms window =-1 repeat atInterval = 0 count = 0
    Operation = PendingInentent{429e4500: PendingInentRecord {429dbbc8 com.android.chrome BroadcastInent}}

    什么是“ num = 1”、“ start = 1369361”和“ end = 1407261”?
    B“ RTC”代表 RTC 警报,我猜。
    “0”代表什么?
    “ type = 1”是什么意思?
    ‘ when = + 19 s304ms’是否意味着警报将在19秒后触发?
    “窗口 =-1”是什么意思?
    重复间隔 = 0是否意味着这是非重复警报?
    “ count = 0”是否意味着此警报没有因为手机睡眠状态而延迟?
    I.‘ operation = PendingInant { ... }’表示未决意图,我假设这个未决意图将由警报触发。

  3. 广播裁判: 0

    这是什么?

  4. 返回文章页面最高警报:

    这是什么?

  5. + 47 s271ms running,0 wakeup,2 alarms: com.username.weatherinfo + 47 s271ms 运行,0唤醒,2警报: com.username.weatherinfo
    Act = com.username.Receivers. CyclicWeatherUpdater.WEAther _ UPDATE _ ACTION
    Cmp = { com.username.weatherinfo/com.username.Receivers. CyclicWeatherUpdater }

    “ + 47s271ms”是否意味着此警报将在47秒后触发?
    什么是’0唤醒’-警报从未被触发?
    什么是“两个警报”?
    “ com.username.weatherinfo”是否代表包的名称,它在上下文字段中被赋予挂起的意图?
    “行动”是否意味着行动,这是意图发送?
    F.什么是‘ cmp’?我明白了,它是由包名和类名组成的——但是它们是从哪里来的呢?从意图构造函数? 克。为什么部分警报只有“ act”或“ cmp”?我假设,没有“ cmp”字段的警报是为了隐含的广播意图。然而,为什么没有“行为”字段的警报?

  6. 警报统计:

    这是什么?

26075 次浏览

我知道这个帖子很旧了,但是答案不容易找到,可能会有用。我花了很长时间才弄明白这些信息是什么意思。

问题1: 批次

Pending alarm batches: 23

警报被分批组织。 如文档中所述:

从 API 19开始,传递给这个方法的触发时间被视为不精确: 在此之前不会传递警报,但可能会推迟并在一段时间之后传递。操作系统将使用这种策略,以便在整个系统中共同使用 “批次”报警器,最大限度地减少设备需要“唤醒”的次数,并最大限度地减少电池使用。一般来说,预定在不久的将来发出的警报不会像预定在远的将来发出的警报那样被推迟。

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

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

其中:

  • 4293d3a8是与批处理相关联的内部 ID。
  • num=1是这批报警器的数量。在本例中,这批报警器中只有一个。
  • startend数字表示自系统上次以 在这篇文章中描述的形式重新启动以来已经过去的毫秒数,也粗略地表示应该触发批处理中的警报的时间窗口。

问题2: 警报

每个报警器都由三条线描述,看起来像是:

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=指的是两个内部常数之一,这两个常数与报警器的批处理方法有关。当与 setExact()setAlarmClock()调度报警时,设置为 AlarmManager.WINDOW_EXACT=0AlarmManager.WINDOW_HEURISTIC=-1和设置时,警报是预定与 setInexactRepeating()。否则,该值由 API 版本确定。对于 API < 19(KitKat) ,使用 WINDOW_EXACT; 对于 API > = 19,使用 WINDOW_HEURISTIC。(我不得不用 深入研究 AlarmManager.java的源代码来解决这个问题。)
  • repeatInterval=900000是警报重复的频率,例如每900000ms 或15分钟。值为0表示警报不会重复。
  • count=指的是警报 应该被触发的次数,而 不是由于某种原因被触发的次数。0在这里是一个很好的数字。 > 0表示由于某种原因跳过了警报。
  • operation=PendingIntent{...}是由警报触发的 PendingIntent的引用。根据 PendingIntent是否使用 getServicegetBroadcastgetActivitygetActivities实例化,警报将启动服务、发送广播或启动一个或多个活动。

问题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
...

与:

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

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

摘要

使用 adb shell dumpsys alarm的输出调试 android 警报可能很棘手,而且没有完整解释 dumpsys消息的中心位置。警报是如何批处理在一起的并不总是很明显,有时很难在需要的时候准确地触发服务或活动。希望这将是有用的参考,人们试图调试他们的警报。

作为一个与警报作斗争的人,这里有两条建议:

调试 shell 输出:

  • 看到负的或者大的时间(例如 -2 hr57m20s311ms,14 d5 hr23m07s500ms) ,是因为我混淆了时钟的类型(例如。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()

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

Https://github.com/dottorhouse/dumpsysalarm