Lesen der Ausgabe von "adb shell dumpsys alarm"

74

Ich habe Probleme damit, einen Alarm richtig einzustellen und den Mechanismus zum Abbrechen und Neuplanen von Alarmen zu verstehen.

Ich habe festgestellt, dass es einen adb-Befehl zum Abrufen aller auf dem Gerät geplanten Alarme gibt, aber ich habe keine Dokumentation gefunden, in der das Format der Ausgabe erläutert wird.

Ich verstehe, dass ich hier viele Erklärungen verlange. Wenn also jemand einen Link mit detaillierten Erklärungen zu "adb shell dumpsys alarm" wirft, werde ich das wirklich zu schätzen wissen.

Also, hier sind die Fragen:

  1. Ausstehende Alarmchargen: 23

    ein. Ist '23' eine Anzahl von derzeit aktiven, geplanten Alarmen?

  2. Stapel {4293d3a8 num = 1 start = 1369361 end = 1407261}:
      RTC # 0: Alarm {4293d358 Typ 1 com.android.chrome}
        Typ = 1 whenElapsed = 1369361 when = + 19s304ms window = -1 repeatInterval = 0 count = 0
        operation = PendingIntent {429e4500: PendingIntentRecord {429dbbc8 com.android.chrome BroadcastIntent}}

    ein. Was ist 'num = 1', 'start = 1369361' und 'end = 1407261'?
    b. 'RTC' steht für RTC-Alarm, nehme ich an.
    c. Wofür steht '# 0'?
    d. Was bedeutet "Typ = 1"?
    e. Bedeutet 'when = + 19s304ms', dass der Alarm in 19 Sekunden ausgelöst wird?
    f. Was bedeutet "Fenster = -1"?
    G. Bedeutet 'repeatInterval = 0', dass dies ein sich nicht wiederholender Alarm ist?
    h. Bedeutet 'count = 0', dass dieser Alarm aufgrund des Ruhezustands des Telefons nicht verschoben wurde?
    ich. 'operation = PendingIntent {...}' steht für die ausstehende Absicht, die vermutlich durch einen Alarm ausgelöst wird.

  3. Anzahl der Broadcast-Refs: 0

    ein. Was ist das?

  4. Top Alarme:

    ein. Was ist das?

  5. + 47s271ms läuft, 0 Weckrufe, 2 Alarme: com.username.weatherinfo
      act = com.username.receivers.CyclicWeatherUpdater.WEATHER_UPDATE_ACTION
        cmp = {com.username.weatherinfo / com.username.receivers.CyclicWeatherUpdater}

    ein. Bedeutet '+ 47s271ms', dass dieser Alarm in 47 Sekunden ausgelöst wird?
    b. Was ist '0 Wakeups' - Alarm wurde nie ausgelöst?
    c. Was ist "2 Alarme"?
    d. Steht 'com.username.weatherinfo' für den Namen des Pakets, das für ausstehende Absichten im Kontextfeld angegeben wurde?
    e. Bedeutet "Handlung" die Handlung, die zur Absicht gesendet wurde?
    f. Was ist "cmp"? Ich sehe, dass es sich aus Paketname und Klassenname zusammensetzt - aber woher stammen sie? Vom Intent-Konstruktor? G. Warum hat ein Teil der Alarme nur "act" oder nur "cmp"? Ich habe angenommen, dass Alarme ohne 'cmp'-Felder für implizite Broadcast-Absichten sind. Warum gibt es jedoch Alarme ohne Aktionsfeld?

  6. Alarmstatistik:

    ein. Was ist das?

Eugene Shtoka
quelle
Angenommen, Sie haben wahrscheinlich bereits die API-Dokumente für den AlarmManager gelesen, würde mein nächster Schritt wahrscheinlich darin bestehen, einige der relevanten AOSP-Quellcodes zu lesen: android.googlesource.com/platform/frameworks/base/+/… (Das scheint kitkat zu sein sind umgezogen oder haben sich seitdem verändert)
Chris Stratton
@ChrisStratton - Hätte er die AlarmManager-Dokumente gelesen, hätte er nicht die Hälfte der Fragen gestellt. Und in Lollipop wurden "Kerndienste" in den coreUnterordner verschoben
Alex P.
1
@Alex P. Anstatt sinnlose Kommentare zu dem Rat abzugeben, hat die andere Person mich bitte auf eine Antwort auf mindestens eine von sechs Fragen hingewiesen, die ich gestellt habe und die in API-Dokumenten für AlarmManager zu finden sind. Es sollte für Sie sehr einfach sein, da es Ihrem Kommentar zufolge mindestens drei Antworten gibt.
Eugene Shtoka

Antworten:

168

Mir ist klar, dass dieser Thread alt ist, aber die Antworten sind nicht leicht zu finden und könnten von Nutzen sein. Ich habe viel Zeit damit verbracht, herauszufinden, was diese Nachrichten bedeuten.

Q1: Chargen

Pending alarm batches: 23

Alarme sind in Stapeln organisiert. Wie in der Dokumentation beschrieben :

Ab API 19 wird die an diese Methode übergebene Auslösezeit als ungenau behandelt: Der Alarm wird nicht vor dieser Zeit übermittelt, kann jedoch verschoben und einige Zeit später übermittelt werden. Das Betriebssystem verwendet diese Richtlinie, um Alarme im gesamten System zu "stapeln", um die Häufigkeit zu minimieren, mit der das Gerät "aufwachen" muss, und um den Batterieverbrauch zu minimieren. Im Allgemeinen werden in naher Zukunft geplante Alarme nicht zurückgestellt, solange weit in der Zukunft geplante Alarme vorliegen.

Es kann mehr als einen Alarm pro Charge geben. In diesem Fall gibt es 23 Chargen von Alarmen, was bedeutet, dass wahrscheinlich viel mehr als 23 Alarme geplant sind. In der dumpsys alarmAusgabe sieht die Zeile, die jede Charge beschreibt, folgendermaßen aus:

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

In welchem:

  • 4293d3a8 ist eine interne ID, die dem Stapel zugeordnet ist.
  • num=1ist die Anzahl der Alarme in dieser Charge. In diesem Fall gibt es nur einen Alarm im Stapel.
  • die startund endZahlen repräsentieren die Anzahl der Millisekunden , die vergangen sind , seit dem System zuletzt als neu gestartet wurde beschrieben in diesem Beitrag , und auch grob repräsentiert das Zeitfenster , in dem die Alarme im Batch ausgelöst werden.

Q2: Alarme

Jeder Alarm wird durch drei Zeilen beschrieben, die wie folgt aussehen:

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}}

In welchem:

  • Der erste Teil, die eine der ist RTC_WAKEUP, RTC, ELAPSED_WAKEUP, oder ELAPSEDrepräsentiert der typevon Alarm- und entspricht einem ganzzahligen Wert 0-3 bzw.
  • #0ist die Nummer des Alarms innerhalb der Charge, wo Zahlen von 0 zu gehen , n-1wo ndie Anzahl der Alarme im Batch ist. Wenn Ihr Alarm mit anderen gestapelt wird, definiert das am weitesten entfernte "when =" die Zeit, zu der alle Alarme im Batch ausgelöst werden.
  • 4293d358 ist eine interne ID-Nummer, die dem Alarm zugeordnet ist
  • com.android.chrome ist der Paketname der Klasse, die den Alarm gesetzt hat
  • type=1, die Art des Alarms, siehe erste Kugel oben
  • whenElapsed=1369361 bezieht sich auf die Anzahl der Millisekunden seit dem Start des Systems, bei der dieser Alarm ausgelöst wird (ungefähr)
  • when=+19s304msbedeutet, dass der Alarm in 19 Sekunden ausgelöst wird, 304 Millisekunden nach dem Zeitpunkt des Aufrufs dumpsys alarm. Ebenso +2d13h29m03s882msbezieht sich ein Wert wie auf eine relative Zeit von 2 Tagen, 13 Stunden, 29 Minuten ... in der Zukunft
  • window=bezieht sich auf eine von zwei internen Konstanten, die mit der Methode zu tun haben, mit der der Alarm gestapelt wird. AlarmManager.WINDOW_EXACT=0und wird eingestellt, wenn der Alarm mit setExact()oder geplant wird setAlarmClock(). AlarmManager.WINDOW_HEURISTIC=-1und wird eingestellt, wenn der Alarm mit geplant ist setInexactRepeating(). Andernfalls wird der Wert von der API-Version bestimmt. Für API <19 (KitKat) WINDOW_EXACTwird verwendet und für API> = 19 WINDOW_HEURISTICwird verwendet. (Ich musste mich in den AlarmManager.javaQuellcode vertiefen, um das herauszufinden.)
  • repeatInterval=900000ist, wie oft der Alarm wiederholt wird, z. B. alle 900000 ms oder 15 Minuten. Ein Wert von 0 bedeutet, dass der Alarm nicht wiederholt wird.
  • count=bezieht sich auf die Häufigkeit, mit der ein Alarm hätte ausgelöst werden sollen, jedoch nicht aus irgendeinem Grund. 0 ist hier eine gute Zahl. > 0 bedeutet, dass der Alarm aus irgendeinem Grund übersprungen wurde.
  • operation=PendingIntent{...}ist ein Verweis auf das PendingIntent, was durch den Alarm ausgelöst wird. Abhängig davon, ob der Alarm mit PendingIntent,, oder instanziiert getServicewurde getBroadcast, startet der Alarm einen Dienst, sendet eine Sendung oder startet eine oder mehrere Aktivitäten.getActivitygetActivities

F3: Broadcast Ref Count

Um dies und die anderen Ausgabeelemente danach herauszufinden, musste ich mich mit dem AlarmManagerService.javaQuellcode befassen .

Damit einige Alarme funktionieren, muss das Gerät aufgeweckt werden und sollte erst wieder in den Ruhezustand versetzt werden, wenn alle erforderlichen Sendungen gesendet wurden. Die interne Variable mBroadcastRefCountwird bei 0 initialisiert und erhöht, wenn zu sendende Broadcasts in die Warteschlange gestellt werden. Wenn jede Sendung gesendet wird, wird sie dekrementiert. Wenn sie auf 0 zurückkehrt, wakeLockwird sie freigegeben und das Gerät kann wieder in den Ruhezustand versetzt werden.

Broadcast Ref Count: 0bedeutet einfach, dass zum Zeitpunkt der dumpsys alarmAusführung keine Sendungen gesendet wurden.

F4: Top-Alarme

Dies sind die zehn häufigsten Alarme, die in absteigender Reihenfolge nach der Gesamtlaufzeit des Alarmcodes geordnet sind. Dies kann verwendet werden, um Alarme zu finden, die die meisten Systemressourcen verbrauchen, z. B. um Prozesse zu finden, bei denen möglicherweise die Batterielebensdauer erschöpft ist.

F5: Alarmstatistik

In diesem Abschnitt werden Statistiken für alle Alarme angezeigt, die seit dem letzten Neustart des Systems ausgeführt wurden. Hier können Sie nachsehen, ob die in der Vergangenheit eingestellten Alarme ausgelöst wurden, ob sie das Telefon aufgeweckt haben usw. Das Format dieser Einträge wird als Nächstes behandelt.

F6: Einträge für Alarmstatistiken

Einträge für Alarmstatistiken sehen folgendermaßen aus:

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}

wo in der ersten Zeile:

  • com.example.someapp ist der Paketname des Prozesses, der den Alarm ausgelöst hat
  • +1s857ms running ist die gesamte Systemzeit, die von den Prozessen verbraucht wird
  • 0 wakeups gibt an, wie oft das Gerät durch einen dieser Alarme geweckt wurde

und dann bezieht sich jede Zeile danach auf einen der eingestellten Alarme mit:

  • +1s817ms ist die gesamte Systemzeit
  • 0 wakes ist die Häufigkeit, mit der das Gerät geweckt werden musste
  • 83 alarmsist die Häufigkeit, mit der der Alarm ausgelöst wurde; Dies ist nur> 1 für wiederholte Alarme
  • cmp={...} Der Dienst, der gestartet wurde, als der Alarm ausgelöst wurde

Wenn der Alarm eine Sendung auslöste, könnte der Eintrag alternativ wie folgt aussehen:

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

mit:

  • act=... ist der Name der Absicht, die ausgestrahlt wurde

Es ist möglich, dass ein Alarm sowohl einen cmp={...}als auch einen act=...Eintrag hat, was bedeutet, dass der Alarm sowohl eine Absicht sendet als auch einen Dienst startet.

Zusammenfassung

Das Debuggen von Android-Alarmen mithilfe der Ausgabe von adb shell dumpsys alarmkann schwierig sein, und es gibt keinen zentralen Ort, an dem die dumpsysNachrichten vollständig erklärt werden. Es ist nicht immer ersichtlich, wie Alarme zusammengefügt werden, und manchmal ist es schwierig, einen Dienst oder eine Aktivität genau dann auszulösen, wenn dies gewünscht wird. Hoffentlich ist dies eine nützliche Referenz für Leute, die versuchen, ihre Alarme zu debuggen.

morphatisch
quelle
5

Als jemand, der auch mit Alarmen zu kämpfen hatte, sind hier zwei Tipps:

Shell-Ausgabe debuggen:

  • Negative oder große Zeiten zu sehen (z. B. -2hr57m20s311ms, 14d5hr23m07s500ms), lag daran, dass ich den Uhrentyp (z. B. RTC mit ELAPSED) verwechselt habe. Dies wird in der Dokumentation " RTC_WAKEUP: Alarm time in System.currentTimeMillis()" https://developer.android.com/reference/android/app/AlarmManager.html#RTC_WAKEUP deutlich

  • Alarme in Echtzeit (nach dem Erstellen) abbrechen. Verwenden Sie den Abbruch. Wenn Sie eine ausstehende Absicht geplant haben, benötigen Sie sowohl: alarmManager.cancel(pendingIntent)als auchpendingIntent.cancel()

Jason
quelle
3

Obwohl die Antwort von morphatic alles ist, was Sie wissen müssen, habe ich ein Open-Source-Projekt für eine GUI erstellt, um dieselben Informationen auf visuelle Weise anzuzeigen. Ich denke, es könnte für andere nützlich sein, da es in erster Linie für mich war.

https://github.com/Dottorhouse/DumpsysAlarm

Dario R.
quelle