dumpsys alarm 简介

一. dumpsys 找到AlarmManagerService

整个过程可以概括为以下几个关键步骤:

  1. 用户输入命令 :在 adb shell 中执行 dumpsys alarm

  2. dumpsys 工具解析dumpsys 二进制工具解析命令参数。

  3. 查找服务 :通过 BinderServiceManager 找到 AlarmManagerService 的 Binder 接口。

  4. 发起远程调用dumpsys 通过 Binder IPC 调用 AlarmManagerServicedump 方法。

  5. 服务处理请求AlarmManagerService.dump() 方法执行,收集数据并写入输出流。

二. dump 命令AlarmManagerService 端

frameworks/base/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java

protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {

//权限检查

if (!DumpUtils.checkDumpAndUsageStatsPermission(getContext(), TAG, pw)) return;

if (args.length > 0 && "--proto".equals(args[0])) {

dumpProto(fd);

} else {

///M:Change for dynamic enable alarmManager log @{

// MTK 针对

dumpImpl (new IndentingPrintWriter(pw, " "));

dumpWithargs (pw, args);

///@}

}

}

dumpImpl 函数:

@NeverCompile // Avoid size overhead of debugging code.

void dumpImpl (IndentingPrintWriter pw) {

synchronized (mLock) {

pw.println("Current Alarm Manager state:");

//缩进符号

pw.increaseIndent();

//mConstants 进行dump

mConstants.dump(pw);

pw.println();

pw.println("Feature Flags:");

pw.increaseIndent();

pw.print(Flags.FLAG_USE_FROZEN_STATE_TO_DROP_LISTENER_ALARMS,

mUseFrozenStateToDropListenerAlarms);

pw.println();

pw.print(Flags.FLAG_START_USER_BEFORE_SCHEDULED_ALARMS,

mStartUserBeforeScheduledAlarms);

pw.decreaseIndent();

pw.println();

pw.println();

pw.println("App Standby Parole: " + mAppStandbyParole);

pw.println();

if (mAppStateTracker != null) {

mAppStateTracker.dump(pw);

pw.println();

}

final long nowELAPSED = mInjector.getElapsedRealtimeMillis();

final long nowUPTIME = SystemClock.uptimeMillis();

final long nowRTC = mInjector.getCurrentTimeMillis();

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

pw.print("nowRTC=");

pw.print(nowRTC);

pw.print("=");

pw.print(sdf.format(new Date(nowRTC)));

pw.print(" nowELAPSED=");

pw.print(nowELAPSED);

pw.println();

pw.print("mLastTimeChangeClockTime=");

pw.print(mLastTimeChangeClockTime);

pw.print("=");

pw.println(sdf.format(new Date(mLastTimeChangeClockTime)));

pw.print("mLastTimeChangeRealtime=");

pw.println(mLastTimeChangeRealtime);

pw.print("mLastTickReceived=");

pw.println(sdf.format(new Date(mLastTickReceived)));

pw.print("mLastTickSet=");

pw.println(sdf.format(new Date(mLastTickSet)));

if (RECORD_ALARMS_IN_HISTORY) {

pw.println();

pw.println("Recent TIME_TICK history:");

pw.increaseIndent();

int i = mNextTickHistory;

do {

i--;

if (i < 0) i = TICK_HISTORY_DEPTH - 1;

final long time = mTickHistory[i];

pw.println((time > 0)

? sdf.format(new Date(nowRTC - (nowELAPSED - time)))

: "-");

} while (i != mNextTickHistory);

pw.decreaseIndent();

}

SystemServiceManager ssm = LocalServices.getService(SystemServiceManager.class);

if (ssm != null) {

pw.println();

pw.print("RuntimeStarted=");

pw.print(sdf.format(

new Date(nowRTC - nowELAPSED + ssm.getRuntimeStartElapsedTime())));

if (ssm.isRuntimeRestarted()) {

pw.print(" (Runtime restarted)");

}

pw.println();

pw.print("Runtime uptime (elapsed): ");

TimeUtils.formatDuration(nowELAPSED, ssm.getRuntimeStartElapsedTime(), pw);

pw.println();

pw.print("Runtime uptime (uptime): ");

TimeUtils.formatDuration(nowUPTIME, ssm.getRuntimeStartUptime(), pw);

pw.println();

}

pw.println();

if (!mInteractive) {

pw.print("Time since non-interactive: ");

TimeUtils.formatDuration(nowELAPSED - mNonInteractiveStartTime, pw);

pw.println();

}

pw.print("Max wakeup delay: ");

TimeUtils.formatDuration(currentNonWakeupFuzzLocked(nowELAPSED), pw);

pw.println();

pw.print("Time since last dispatch: ");

TimeUtils.formatDuration(nowELAPSED - mLastAlarmDeliveryTime, pw);

pw.println();

pw.print("Next non-wakeup delivery time: ");

TimeUtils.formatDuration(mNextNonWakeupDeliveryTime, nowELAPSED, pw);

pw.println();

long nextWakeupRTC = mNextWakeup + (nowRTC - nowELAPSED);

long nextNonWakeupRTC = mNextNonWakeup + (nowRTC - nowELAPSED);

pw.print("Next non-wakeup alarm: ");

TimeUtils.formatDuration(mNextNonWakeup, nowELAPSED, pw);

pw.print(" = ");

pw.print(mNextNonWakeup);

pw.print(" = ");

pw.println(sdf.format(new Date(nextNonWakeupRTC)));

pw.increaseIndent();

pw.print("set at ");

TimeUtils.formatDuration(mNextNonWakeUpSetAt, nowELAPSED, pw);

pw.decreaseIndent();

pw.println();

pw.print("Next wakeup alarm: ");

TimeUtils.formatDuration(mNextWakeup, nowELAPSED, pw);

pw.print(" = ");

pw.print(mNextWakeup);

pw.print(" = ");

pw.println(sdf.format(new Date(nextWakeupRTC)));

pw.increaseIndent();

pw.print("set at ");

TimeUtils.formatDuration(mNextWakeUpSetAt, nowELAPSED, pw);

pw.decreaseIndent();

pw.println();

pw.print("Next kernel non-wakeup alarm: ");

TimeUtils.formatDuration(mInjector.getNextAlarm(ELAPSED_REALTIME), pw);

pw.println();

pw.print("Next kernel wakeup alarm: ");

TimeUtils.formatDuration(mInjector.getNextAlarm(ELAPSED_REALTIME_WAKEUP), pw);

pw.println();

pw.print("Last wakeup: ");

TimeUtils.formatDuration(mLastWakeup, nowELAPSED, pw);

pw.print(" = ");

pw.println(mLastWakeup);

pw.print("Last trigger: ");

TimeUtils.formatDuration(mLastTrigger, nowELAPSED, pw);

pw.print(" = ");

pw.println(mLastTrigger);

pw.print("Num time change events: ");

pw.println(mNumTimeChanged);

pw.println();

pw.println("App ids requesting SCHEDULE_EXACT_ALARM: " + mExactAlarmCandidates);

pw.println();

pw.print("Last OP_SCHEDULE_EXACT_ALARM: [");

for (int i = 0; i < mLastOpScheduleExactAlarm.size(); i++) {

if (i > 0) {

pw.print(", ");

}

UserHandle.formatUid(pw, mLastOpScheduleExactAlarm.keyAt(i));

pw.print(":" + AppOpsManager.modeToName(mLastOpScheduleExactAlarm.valueAt(i)));

}

pw.println("]");

pw.println();

pw.println("Next alarm clock information: ");

pw.increaseIndent();

final TreeSet<Integer> users = new TreeSet<>();

for (int i = 0; i < mNextAlarmClockForUser.size(); i++) {

users.add(mNextAlarmClockForUser.keyAt(i));

}

for (int i = 0; i < mPendingSendNextAlarmClockChangedForUser.size(); i++) {

users.add(mPendingSendNextAlarmClockChangedForUser.keyAt(i));

}

for (int user : users) {

final AlarmManager.AlarmClockInfo next = mNextAlarmClockForUser.get(user);

final long time = next != null ? next.getTriggerTime() : 0;

final boolean pendingSend = mPendingSendNextAlarmClockChangedForUser.get(user);

pw.print("user:");

pw.print(user);

pw.print(" pendingSend:");

pw.print(pendingSend);

pw.print(" time:");

pw.print(time);

if (time > 0) {

pw.print(" = ");

pw.print(sdf.format(new Date(time)));

pw.print(" = ");

TimeUtils.formatDuration(time, nowRTC, pw);

}

pw.println();

}

pw.decreaseIndent();

if (mAlarmStore.size() > 0) {

pw.println();

mAlarmStore.dump(pw, nowELAPSED, sdf);

}

pw.println();

pw.println("Pending user blocked background alarms: ");

pw.increaseIndent();

boolean blocked = false;

for (int i = 0; i < mPendingBackgroundAlarms.size(); i++) {

final ArrayList<Alarm> blockedAlarms = mPendingBackgroundAlarms.valueAt(i);

if (blockedAlarms != null && blockedAlarms.size() > 0) {

blocked = true;

dumpAlarmList(pw, blockedAlarms, nowELAPSED, sdf);

}

}

if (!blocked) {

pw.println("none");

}

pw.decreaseIndent();

pw.println();

pw.print("Pending alarms per uid: [");

for (int i = 0; i < mAlarmsPerUid.size(); i++) {

if (i > 0) {

pw.print(", ");

}

UserHandle.formatUid(pw, mAlarmsPerUid.keyAt(i));

pw.print(":");

pw.print(mAlarmsPerUid.valueAt(i));

}

pw.println("]");

pw.println();

if (mStartUserBeforeScheduledAlarms) {

pw.println("Scheduled user wakeups:");

mUserWakeupStore.dump(pw, nowELAPSED);

pw.println();

}

pw.println("App Alarm history:");

mAppWakeupHistory.dump(pw, nowELAPSED);

pw.println();

pw.println("Temporary Quota Reserves:");

mTemporaryQuotaReserve.dump(pw, nowELAPSED);

if (mPendingIdleUntil != null) {

pw.println();

pw.println("Idle mode state:");

pw.increaseIndent();

pw.print("Idling until: ");

if (mPendingIdleUntil != null) {

pw.println(mPendingIdleUntil);

mPendingIdleUntil.dump(pw, nowELAPSED, sdf);

} else {

pw.println("null");

}

pw.decreaseIndent();

}

if (mNextWakeFromIdle != null) {

pw.println();

pw.print("Next wake from idle: ");

pw.println(mNextWakeFromIdle);

pw.increaseIndent();

mNextWakeFromIdle.dump(pw, nowELAPSED, sdf);

pw.decreaseIndent();

}

pw.println();

pw.print("Past-due non-wakeup alarms: ");

if (mPendingNonWakeupAlarms.size() > 0) {

pw.println(mPendingNonWakeupAlarms.size());

pw.increaseIndent();

dumpAlarmList(pw, mPendingNonWakeupAlarms, nowELAPSED, sdf);

pw.decreaseIndent();

} else {

pw.println("(none)");

}

pw.increaseIndent();

pw.print("Number of delayed alarms: ");

pw.print(mNumDelayedAlarms);

pw.print(", total delay time: ");

TimeUtils.formatDuration(mTotalDelayTime, pw);

pw.println();

pw.print("Max delay time: ");

TimeUtils.formatDuration(mMaxDelayTime, pw);

pw.print(", max non-interactive time: ");

TimeUtils.formatDuration(mNonInteractiveTime, pw);

pw.println();

pw.decreaseIndent();

pw.println();

pw.print("Broadcast ref count: ");

pw.println(mBroadcastRefCount);

pw.print("PendingIntent send count: ");

pw.println(mSendCount);

pw.print("PendingIntent finish count: ");

pw.println(mSendFinishCount);

pw.print("Listener send count: ");

pw.println(mListenerCount);

pw.print("Listener finish count: ");

pw.println(mListenerFinishCount);

pw.println();

if (mInFlight.size() > 0) {

pw.println("Outstanding deliveries:");

pw.increaseIndent();

for (int i = 0; i < mInFlight.size(); i++) {

pw.print("#");

pw.print(i);

pw.print(": ");

pw.println(mInFlight.get(i));

}

pw.decreaseIndent();

pw.println();

}

pw.println("Allow while idle history:");

mAllowWhileIdleHistory.dump(pw, nowELAPSED);

pw.println();

pw.println("Allow while idle compat history:");

mAllowWhileIdleCompatHistory.dump(pw, nowELAPSED);

pw.println();

if (mLastPriorityAlarmDispatch.size() > 0) {

pw.println("Last priority alarm dispatches:");

pw.increaseIndent();

for (int i = 0; i < mLastPriorityAlarmDispatch.size(); i++) {

pw.print("UID: ");

UserHandle.formatUid(pw, mLastPriorityAlarmDispatch.keyAt(i));

pw.print(": ");

TimeUtils.formatDuration(mLastPriorityAlarmDispatch.valueAt(i), nowELAPSED, pw);

pw.println();

}

pw.decreaseIndent();

}

if (mRemovalHistory.size() > 0) {

pw.println("Removal history:");

pw.increaseIndent();

for (int i = 0; i < mRemovalHistory.size(); i++) {

UserHandle.formatUid(pw, mRemovalHistory.keyAt(i));

pw.println(":");

pw.increaseIndent();

final RemovedAlarm[] historyForUid = mRemovalHistory.valueAt(i).toArray();

for (int index = historyForUid.length - 1; index >= 0; index--) {

pw.print("#" + (historyForUid.length - index) + ": ");

historyForUid[index].dump(pw, nowELAPSED, sdf);

}

pw.decreaseIndent();

}

pw.decreaseIndent();

pw.println();

}

if (mLog.dump(pw, "Recent problems:")) {

pw.println();

}

final FilterStats[] topFilters = new FilterStats[10];

final Comparator<FilterStats> comparator = new Comparator<FilterStats>() {

@Override

public int compare(FilterStats lhs, FilterStats rhs) {

if (lhs.aggregateTime < rhs.aggregateTime) {

return 1;

} else if (lhs.aggregateTime > rhs.aggregateTime) {

return -1;

}

return 0;

}

};

int len = 0;

// Get the top 10 FilterStats, ordered by aggregateTime.

for (int iu = 0; iu < mBroadcastStats.size(); iu++) {

ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(iu);

for (int ip = 0; ip < uidStats.size(); ip++) {

BroadcastStats bs = uidStats.valueAt(ip);

for (int is = 0; is < bs.filterStats.size(); is++) {

FilterStats fs = bs.filterStats.valueAt(is);

int pos = len > 0

? Arrays.binarySearch(topFilters, 0, len, fs, comparator) : 0;

if (pos < 0) {

pos = -pos - 1;

}

if (pos < topFilters.length) {

int copylen = topFilters.length - pos - 1;

if (copylen > 0) {

System.arraycopy(topFilters, pos, topFilters, pos + 1, copylen);

}

topFilters[pos] = fs;

if (len < topFilters.length) {

len++;

}

}

}

}

}

if (len > 0) {

pw.println("Top Alarms:");

pw.increaseIndent();

for (int i = 0; i < len; i++) {

FilterStats fs = topFilters[i];

if (fs.nesting > 0) pw.print("*ACTIVE* ");

TimeUtils.formatDuration(fs.aggregateTime, pw);

pw.print(" running, ");

pw.print(fs.numWakeup);

pw.print(" wakeups, ");

pw.print(fs.count);

pw.print(" alarms: ");

UserHandle.formatUid(pw, fs.mBroadcastStats.mUid);

pw.print(":");

pw.print(fs.mBroadcastStats.mPackageName);

pw.println();

pw.increaseIndent();

pw.print(fs.mTag);

pw.println();

pw.decreaseIndent();

}

pw.decreaseIndent();

}

pw.println();

pw.println("Alarm Stats:");

final ArrayList<FilterStats> tmpFilters = new ArrayList<FilterStats>();

for (int iu = 0; iu < mBroadcastStats.size(); iu++) {

ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(iu);

for (int ip = 0; ip < uidStats.size(); ip++) {

BroadcastStats bs = uidStats.valueAt(ip);

if (bs.nesting > 0) pw.print("*ACTIVE* ");

UserHandle.formatUid(pw, bs.mUid);

pw.print(":");

pw.print(bs.mPackageName);

pw.print(" ");

TimeUtils.formatDuration(bs.aggregateTime, pw);

pw.print(" running, ");

pw.print(bs.numWakeup);

pw.println(" wakeups:");

tmpFilters.clear();

for (int is = 0; is < bs.filterStats.size(); is++) {

tmpFilters.add(bs.filterStats.valueAt(is));

}

Collections.sort(tmpFilters, comparator);

pw.increaseIndent();

for (int i = 0; i < tmpFilters.size(); i++) {

FilterStats fs = tmpFilters.get(i);

if (fs.nesting > 0) pw.print("*ACTIVE* ");

TimeUtils.formatDuration(fs.aggregateTime, pw);

pw.print(" ");

pw.print(fs.numWakeup);

pw.print(" wakes ");

pw.print(fs.count);

pw.print(" alarms, last ");

TimeUtils.formatDuration(fs.lastTime, nowELAPSED, pw);

pw.println(":");

pw.increaseIndent();

pw.print(fs.mTag);

pw.println();

pw.decreaseIndent();

}

pw.decreaseIndent();

}

}

pw.println();

mStatLogger.dump(pw);

if (RECORD_DEVICE_IDLE_ALARMS) {

pw.println();

pw.println("Allow while idle dispatches:");

pw.increaseIndent();

for (int i = 0; i < mAllowWhileIdleDispatches.size(); i++) {

IdleDispatchEntry ent = mAllowWhileIdleDispatches.get(i);

TimeUtils.formatDuration(ent.elapsedRealtime, nowELAPSED, pw);

pw.print(": ");

UserHandle.formatUid(pw, ent.uid);

pw.print(":");

pw.println(ent.pkg);

pw.increaseIndent();

if (ent.op != null) {

pw.print(ent.op);

pw.print(" / ");

pw.print(ent.tag);

if (ent.argRealtime != 0) {

pw.print(" (");

TimeUtils.formatDuration(ent.argRealtime, nowELAPSED, pw);

pw.print(")");

}

pw.println();

}

pw.decreaseIndent();

}

pw.decreaseIndent();

}

}

}

(1)mConstants dump的函数:

void dump(IndentingPrintWriter pw) {

pw.println("Settings:");

pw.increaseIndent();

pw.print("version", mVersion);

pw.println();

pw.print(KEY_MIN_FUTURITY);

pw.print("=");

TimeUtils.formatDuration(MIN_FUTURITY, pw);

pw.println();

pw.print(KEY_MIN_INTERVAL);

pw.print("=");

TimeUtils.formatDuration(MIN_INTERVAL, pw);

pw.println();

pw.print(KEY_MAX_INTERVAL);

pw.print("=");

TimeUtils.formatDuration(MAX_INTERVAL, pw);

pw.println();

pw.print(KEY_MIN_WINDOW);

pw.print("=");

TimeUtils.formatDuration(MIN_WINDOW, pw);

pw.println();

pw.print(KEY_LISTENER_TIMEOUT);

pw.print("=");

TimeUtils.formatDuration(LISTENER_TIMEOUT, pw);

pw.println();

pw.print(KEY_ALLOW_WHILE_IDLE_QUOTA, ALLOW_WHILE_IDLE_QUOTA);

pw.println();

pw.print(KEY_ALLOW_WHILE_IDLE_WINDOW);

pw.print("=");

TimeUtils.formatDuration(ALLOW_WHILE_IDLE_WINDOW, pw);

pw.println();

pw.print(KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA, ALLOW_WHILE_IDLE_COMPAT_QUOTA);

pw.println();

pw.print(KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW);

pw.print("=");

TimeUtils.formatDuration(ALLOW_WHILE_IDLE_COMPAT_WINDOW, pw);

pw.println();

pw.print(KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION);

pw.print("=");

TimeUtils.formatDuration(ALLOW_WHILE_IDLE_WHITELIST_DURATION, pw);

pw.println();

pw.print(KEY_MAX_ALARMS_PER_UID, MAX_ALARMS_PER_UID);

pw.println();

pw.print(KEY_APP_STANDBY_WINDOW);

pw.print("=");

TimeUtils.formatDuration(APP_STANDBY_WINDOW, pw);

pw.println();

for (int i = 0; i < KEYS_APP_STANDBY_QUOTAS.length; i++) {

pw.print(KEYS_APP_STANDBY_QUOTAS[i], APP_STANDBY_QUOTAS[i]);

pw.println();

}

pw.print(KEY_APP_STANDBY_RESTRICTED_QUOTA, APP_STANDBY_RESTRICTED_QUOTA);

pw.println();

pw.print(KEY_APP_STANDBY_RESTRICTED_WINDOW);

pw.print("=");

TimeUtils.formatDuration(APP_STANDBY_RESTRICTED_WINDOW, pw);

pw.println();

pw.print(KEY_TIME_TICK_ALLOWED_WHILE_IDLE, TIME_TICK_ALLOWED_WHILE_IDLE);

pw.println();

pw.print(KEY_PRIORITY_ALARM_DELAY);

pw.print("=");

TimeUtils.formatDuration(PRIORITY_ALARM_DELAY, pw);

pw.println();

pw.print(KEY_MIN_DEVICE_IDLE_FUZZ);

pw.print("=");

TimeUtils.formatDuration(MIN_DEVICE_IDLE_FUZZ, pw);

pw.println();

pw.print(KEY_MAX_DEVICE_IDLE_FUZZ);

pw.print("=");

TimeUtils.formatDuration(MAX_DEVICE_IDLE_FUZZ, pw);

pw.println();

pw.print(KEY_TEMPORARY_QUOTA_BUMP, TEMPORARY_QUOTA_BUMP);

pw.println();

pw.print(KEY_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF,

DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF);

pw.println();

pw.print(KEY_CACHED_LISTENER_REMOVAL_DELAY);

pw.print("=");

TimeUtils.formatDuration(CACHED_LISTENER_REMOVAL_DELAY, pw);

pw.println();

pw.decreaseIndent();

}

三. Current Alarm Manager state 信息解析:

对应内容:

Current Alarm Manager state:

Settings:

//Alarm Manager 配置的版本号

version=1

//设置一个Alarm 的最小未来触发时间.

//min_futurity有助于避免过于频繁的调度请求。

min_futurity=+5s0ms

//min_interval重复性 Alarm(setRepeating)的最小允许间隔

//任何小于1分钟的请求都会被系统自动提升到1分钟。

min_interval=+1m0s0ms

//Alarm 的最大允许间隔,理论上为一年

max_interval=+365d0h0m0s0ms

//Alarm 批处理窗口的最小长度。

//系统可能会将多个 Alarm 批量处理在这个时间窗口内一起触发以节省电量。

min_window=+10m0s0ms

//当 Alarm 触发时,系统等待 Alarm 监听器响应的超时时间.

//如果超过 5 秒,系统可能会认为该监听器无响应。

listener_timeout=+5s0ms

//每个应用在 每个时间窗口 内可以触发的 allow-while-idle 类型 Alarm 的最大数量。

allow_while_idle_quota=72

//上述配额的时间窗口长度(1小时)。

allow_while_idle_window=+1h0m0s0ms

//为兼容旧版本应用(以旧 API 为目标平台)而保留的 allow-while-idle 配额。数量更少。

allow_while_idle_compat_quota=7

//兼容性配额的时间窗口

allow_while_idle_compat_window=+1h0m0s0ms

//当一个 allow-while-idle Alarm 触发时,系统会将应用临时加入电源白名单约 10 秒,使其可以执行一些网络或其他操作。

allow_while_idle_whitelist_duration=+10s0ms

//单个应用(UID)可以设置的最大触发 Alarm 数量,防止恶意应用耗尽系统资源。

max_alarms_per_uid=500

// 配额计算的时间窗口长度。例如,standby_quota_active=720 表示活跃应用在 1 小时内最多可以触发 720 次 Alarm。

app_standby_window=+1h0m0s0ms

//活跃 状态应用的配额(最高优先级)。

standby_quota_active=720

//工作 状态应用的配额。

standby_quota_working=10

//常用 状态应用的配额。

standby_quota_frequent=2

//罕见 状态应用的配额

standby_quota_rare=1

//从未使用过 的应用的配额(实际上为 0)

standby_quota_never=0

//在 受限 状态下的应用的配额(非常低,通常是由于用户手动限制了应用的后台活动)。

standby_quota_restricted=1

//限制类型的窗口大小

app_standby_restricted_window=+1d0h0m0s0ms

//系统事件 TIME_TICK 是否允许在空闲状态下触发

time_tick_allowed_while_idle=true

//高优先级 Alarm 在设备退出空闲模式后最多可被延迟的时间。

priority_alarm_delay=+9m0s0ms

//当设备处于空闲模式时,系统会对 Alarm 的触发时间添加一个随机延迟("模糊"处理),

//范围在 2 到 15 分钟之间,以防止所有应用同时被唤醒。

min_device_idle_fuzz=+2m0s0ms

max_device_idle_fuzz=+15m0s0ms

//临时补充份额的大小,当份额不够使用时,可以使用临时补充份额

temporary_quota_bump=0

//当屏幕关闭时,是否延迟非唤醒 Alarm(即不会唤醒设备的 Alarm)。

//true 表示延迟,以节省电量。

delay_nonwakeup_alarms_while_screen_off=true

//应用在被缓存后可能会很快被冻结,这会破坏监听器警报的精确性保证.

//今后精确监听器警报的契约明确要求:一旦应用退出生命周期,这些警报将被立即移除

//允许短暂的宽限期,以应对在不同生命周期之间切换时可能意外发生的进程状态快速变动------这种情况通常难以被应用完全避免

// 这里定义延迟10秒再移除缓存进程的监听

cached_listener_removal_delay=+10s0ms

四. Feature Flags 解析

Feature Flags:

//当前进程被冻结时,则移除alarm.

com.android.server.alarm.use_frozen_state_to_drop_listener_alarms=true

// 是否支持多用户alarm的调度

com.android.server.alarm.start_user_before_scheduled_alarms=false

五. App Standby Parole

//当设备处于充电状态时,免除应用待机限制.当前状态为true则说明是应用待机限制处于豁免.

App Standby Parole: true

六. Current AppStateTracker State

Current AppStateTracker State:

//这是一个全局开关,如果为 true,会忽略所有其他规则,将所有应用置于最严格的限制中。通常用于极端省电模式(如某些厂商的"超级省电"模式),此处未启用。

Force all apps standby: false

//当前设备不被认为是小电池设备

Small Battery Device: false

//若设置中启用了针对小电池设备的强制应用待机功能,则为 True

Force all apps standby for small battery device: false

//是否在充电

Plugged In: true

//"活跃"通常指应用正在前台运行,或最近刚从前台退出不久。这些应用不受后台限制的约束

Active uids: [u0a43 u0a103 u0a118 u0a128 u0a131 u0a133 u0a142 u0a165 u0a168 u0a176 u0a191 u0a197]

//列表中的应用不受应用待机桶(App Standby Bucket)的限制。即使设备进入空闲(Idle)状态,它们也能正常执行后台活动。

Except-idle + user exemption list appids: [1001, 2000, 10042, 10044, 10049, 10051, 10053, 10061, 10066, 10087, 10102, 10113, 10115, 10119, 10122, 10125, 10130, 10131, 10162, 10163, 10187, 10188]

//由用户手动设置为"不优化"(即豁免电池优化)的应用ID列表。

User exemption list appids: [1001]

//临时豁免列表

Temp exemption list appids: []

Exempted bucket packages:

//user 0

User 0

//豁免白名单列表

com.google.android.networkstack.tethering

com.mediatek.ims

com.android.providers.telephony

com.android.dynsystem

com.entitlement.settings

com.google.android.cellbroadcastservice

com.android.providers.calendar

com.mediatek.telephony

com.mediatek.location.lppe.main

com.tinno.setupwizard

com.mediatek.simprocessor

com.mediatek.autodialer

com.android.mms.service

com.android.providers.downloads

com.mediatek.datachannel.service

com.google.android.apps.safetyhub

com.android.vending

com.ape.algoprocessservice

android

com.ape.factory

com.android.nfc

com.android.ons

com.android.stk

com.google.android.carrier

com.mediatek.smartratswitch.service

com.aura.oobe.att

com.android.providers.settings

com.android.se

com.android.inputdevices

com.google.android.devicelockcontroller

com.mediatek

com.google.ambient.streaming

com.android.cellbroadcastreceiver

com.google.android.networkstack

com.android.server.telecom

com.android.keychain

com.google.android.gms

com.android.localtransport

com.android.DeviceAsWebcam

com.android.proxyhandler

com.att.iqi

com.mediatek.atci.service

com.mediatek.capctrl.service

com.mediatek.simrecovery

com.android.imsserviceentitlement

com.android.settings

com.android.phone

com.android.shell

com.google.android.apps.carrier.carrierwifi

com.android.emergency

com.android.location.fused

com.att.personalcloud

com.facebook.appmanager

com.aura.jet.att

com.google.android.cellbroadcastreceiver

com.android.bluetooth

com.android.providers.contacts

com.mediatek.gbaservice

//被额外限制的应用包列表

Restricted packages:

Stats:

//原生代码逻辑没有实现

UID_FG_STATE_CHANGED: count=0, total=0.0ms, avg=0.000ms, max calls/s=0 max dur/s=0.0ms max time=0.0ms

//表示应用切换到活跃状态的切换次数

UID_ACTIVE_STATE_CHANGED: count=1060, total=522.8ms, avg=0.493ms, max calls/s=10 max dur/s=35.3ms max time=34.7ms

//运行任何权限变更的次数记录

RUN_ANY_CHANGED: count=0, total=0.0ms, avg=0.000ms, max calls/s=0 max dur/s=0.0ms max time=0.0ms

//所有未豁免的应用次数记录

ALL_UNEXEMPTED: count=0, total=0.0ms, avg=0.000ms, max calls/s=0 max dur/s=0.0ms max time=0.0ms

//"全局豁免列表"发生了变更

ALL_EXEMPTION_LIST_CHANGED: count=0, total=0.0ms, avg=0.000ms, max calls/s=0 max dur/s=0.0ms max time=0.0ms

//临时豁免列表变更的次数

TEMP_EXEMPTION_LIST_CHANGED: count=987, total=2479.1ms, avg=2.512ms, max calls/s=15 max dur/s=67.1ms max time=57.8ms

//豁免待机桶变更

EXEMPTED_BUCKET_CHANGED: count=2, total=0.4ms, avg=0.198ms, max calls/s=1 max dur/s=0.3ms max time=0.3ms

//强制被限制的次数, 譬如:低电量等事件

FORCE_ALL_CHANGED: count=0, total=0.0ms, avg=0.000ms, max calls/s=0 max dur/s=0.0ms max time=0.0ms

//代码未实现

IS_UID_ACTIVE_CACHED: count=0, total=0.0ms, avg=0.000ms, max calls/s=0 max dur/s=0.0ms max time=0.0ms

//检查UID是否活跃(原始查询,就是没有本地缓存,在AppStateTrackerImpl.java中)

IS_UID_ACTIVE_RAW: count=621, total=217.3ms, avg=0.350ms, max calls/s=12 max dur/s=18.2ms max time=14.1ms

七. Time 记录:

//当前RTC和nowELAPSED时间

nowRTC=1756112963361=2025-08-25 17:09:23.361 nowELAPSED=528054181

//最新一次RTC时间被修改时的"当时"的RTC时间

mLastTimeChangeClockTime=1755584949176=2025-08-19 14:29:09.176

//最新一次RTC时间被修改时的"当时"的Realtime时间

mLastTimeChangeRealtime=39995

//最新一次接受到tick alarm的时间

mLastTickReceived=2025-08-25 17:08:18.396

//最新一次设置tick alarm的时间

mLastTickSet=2025-08-25 17:08:18.396

八. Recent TIME_TICK history

//获取最近10次tick time的时间戳

Recent TIME_TICK history:

2025-08-25 17:08:18.395

2025-08-25 17:07:00.000

2025-08-25 17:06:49.936

2025-08-25 17:03:46.211

2025-08-25 16:59:48.210

2025-08-25 16:52:45.724

2025-08-25 16:48:31.211

2025-08-25 16:46:30.209

2025-08-25 16:44:30.188

2025-08-25 16:34:55.212

//Android 运行时(ART)进程启动的准确时间点

RuntimeStarted=2025-08-19 14:28:44.066

//自 ART 启动以来,总共过去了多长时间(包括睡眠时间)

Runtime uptime (elapsed): +6d2h40m39s295ms

//自 ART 启动以来,设备处于唤醒状态、ART 可以实际工作的时间(不包括深度睡眠时间)。

Runtime uptime (uptime): +3d7h38m40s130ms

//距离设备最后一次进入非交互状态 (屏幕关闭)已经过去了 53.077秒

//此时间记录是通过收到 Intent.ACTION_SCREEN_ON 和 Intent.ACTION_SCREEN_OFF广播的时间计算的.

Time since non-interactive: +53s77ms

//系统批处理 Alarm 的窗口时间

//规则:

//如果屏幕关闭时间小于5分钟,则最多仅延迟2分钟

//如果屏幕关闭时间大于5分钟并且30分钟,最多仅延迟15分钟

//如果屏幕关闭时间大于5分钟,则最多仅延迟1小时

Max wakeup delay: +2m0s0ms

//距离上一次分发并处理 Alarm 已经过去了 1分4.966秒

Time since last dispatch: +1m4s966ms

//下一个计划分发非唤醒Alarm的时间点 是在 2分36.638秒后

Next non-wakeup delivery time: +2m36s638ms

//下一个不会唤醒设备 的 Alarm 将在 53.143秒后 (相对于 nowELAPSED)触发。

Next non-wakeup alarm: +53s143ms = 528107324 = 2025-08-25 17:10:16.504

//这个 non wakeup Alarm 是在 23.362秒前 被设置的

set at -23s362ms

//下一个会唤醒设备 的 Alarm 将在 23分13.636秒后 触发

Next wakeup alarm: +23m13s636ms = 529447817 = 2025-08-25 17:32:36.997

//这个 wakeup Alarm 是在 23.362秒前 被设置的

set at -23s362ms

//下一个来自kernel非唤醒alarm是53s139ms 后

Next kernel non-wakeup alarm: +53s139ms

//下一个来自kernel唤醒alarm是23m13s632ms 后

Next kernel wakeup alarm: +23m13s632ms

//最后一次唤醒设备 的 Alarm 的时间是在23s362ms 之前

Last wakeup: -23s362ms = 528030819

//最后一次触发 的 Alarm 都发生在 23.362秒前

Last trigger: -23s362ms = 528030819

//时间变更事件发生了1次

// 此数字是大于等于1, 譬如:手动更改时间,会增加事件的次数

Num time change events: 1

//请求了 SCHEDULE_EXACT_ALARM 权限的应用ID列表

//代码:

//mLocalPermissionManager = LocalServices.getService(

PermissionManagerServiceInternal.class);

// final String[] candidates = mLocalPermissionManager.getAppOpPermissionPackages(

Manifest.permission.SCHEDULE_EXACT_ALARM);

// 通过candidates 获取appid

App ids requesting SCHEDULE_EXACT_ALARM: {1000, 2000, 10061, 10117, 10125, 10128, 10132, 10133, 10146, 10162, 10176, 10184}

//最近一次处理 SCHEDULE_EXACT_ALARM 权限操作(OP = operation)的结果记录,显示了每个应用ID对应的权限状态。

// allow :表示系统明确允许该应用执行安排精确闹钟的操作。这通常意味着用户已经明确授予了该权限。

//default:表示该应用的权限处于默认状态。根据 Android 版本和政策,这可能意味着权限被拒绝或尚未被用户明确授予

Last OP_SCHEDULE_EXACT_ALARM: [1000:allow, 2000:default, u0a61:default, u0a117:default, u0a125:default, u0a128:default, u0a132:allow, u0a133:default, u0a146:default, u0a162:default, u0a176:default, u0a184:default]

九. Next alarm clock information:

// 有61 个待处理的alarm

61 pending alarms:

// alarm 的类型分为: RTC,RTC_WAKEUP,ELAPSED,ELAPSED_WAKEUP,--unknown--

//类型是ELAPSED #1 表示列表中第一个.

// 进程是Android

//tag: alarm 没有带"w",说明不是wakeup 类型的,和 ELAPSED 是一一对应,*job.delay* 是系统 JobScheduler 服务的标签。

//type 是ELAPSED

//origWhen 请求设置 Alarm 时原始的触发时间

**//**window 允许 Alarm 延迟触发的最大时间窗口

//repeatInterval 闹钟两次触发之间的时间间隔,0 表示只执行一次就结束了

//count表示触发的总次数,0表示只触发一次.

//flags 表示设置flag 内容,flag的类型:FLAG_STANDALONE,FLAG_WAKE_FROM_IDLE,FLAG_ALLOW_WHILE_IDLE,

FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED,FLAG_IDLE_UNTIL,

FLAG_ALLOW_WHILE_IDLE_COMPAT,FLAG_PRIORITIZE

// policyWhenElapsed: 系统各种省电策略(如应用待机、设备空闲模式、省电模式)对 Alarm 触发时间的影响-- 表示该策略不适用或时间为0

//requester 表示已经请求时间,-30s611ms 表示已经过30s611ms

//app_standby表示应用待机桶,-2m22s283ms 根据app_standby 调整时间,已经发生了-2m22s283ms

//device_idle: doze 调整时间,-- 表示没有设置

//battery_saver: 低电量的调整时间,-- 表示没有设置

//whenElapsed 表示调整之后的时间,各个策略取最大值.

//maxWhenElapsed 表示最晚触发时间

// listener: 监听的实例.

ELAPSED #1: Alarm{22960b3 type 3 origWhen 528023570 whenElapsed 528023570 android }

tag =*alarm*:*job.delay*

type=ELAPSED origWhen=-30s611ms window=+1m23s754ms repeatInterval=0 count=0 flags=0x0

policyWhenElapsed: requester=-30s611ms app_standby=-2m22s283ms device_idle=-- battery_saver=--

whenElapsed=-30s611ms maxWhenElapsed=+53s143ms

listener=android.app.AlarmManager$ListenerWrapper@486e670

//类型是ELAPSED #4 表示列表中第四个.

// 进程是com.google.android.googlequicksearchbox

//tag: 允许在设备空闲时运行 (ALLOW IDLE)

//exactAllowReason=permission 表示该应用持有 SCHEDULE_EXACT_ALARM 权限,因此允许设置精确的 Alarm。

//operation 表示Alarm 触发时要执行的PendingIntent

// idle-options表示Broadcast带的参数

RTC #4: Alarm{4f550f type 1 origWhen 1756113356667 whenElapsed 528447486 com.google.android.googlequicksearchbox}

tag=*alarm*:TIME TRIGGER ALLOW IDLE ACTION

type=RTC origWhen=2025-08-25 17:15:56.667 window=0 exactAllowReason=permission repeatInterval=0 count=0 flags=0x5

policyWhenElapsed: requester=+6m33s305ms app_standby=-2m25s208ms device_idle=-2m25s309ms battery_saver=-21m37s836ms

whenElapsed=+6m33s305ms maxWhenElapsed=+6m33s305ms

operation=PendingIntent{64bf99c: PendingIntentRecord{f0effa5 com.google.android.googlequicksearchbox broadcastIntent}}

idle-options=Bundle[{android.pendingIntent.backgroundActivityAllowed=2, android:broadcast.temporaryAppAllowlistReasonCode=302, android:broadcast.temporaryAppAllowlistDuration=10000, android:broadcast.temporaryAppAllowlistReason=, android:broadcast.temporaryAppAllowlistType=0, android:broadcast.flags=8}]

//类型是ELAPSED_WAKEUP #4 表示列表中第四个.

ELAPSED_WAKEUP #7: Alarm{9e8e946 type 2 origWhen 529223570 whenElapsed 529223570 android}

tag=*walarm*:*job.deadline*

type=ELAPSED_WAKEUP origWhen=+19m29s389ms window=+16m23s754ms repeatInterval=0 count=0 flags=0x0

policyWhenElapsed: requester=+19m29s389ms app_standby=-2m22s284ms device_idle=-- battery_saver=--

whenElapsed=+19m29s389ms maxWhenElapsed=+35m53s143ms

listener=android.app.AlarmManager$ListenerWrapper@162d707

//类型是 RTC_WAKEUP #13 表示列表中第十三个.

//进程是com.android.settings

RTC_WAKEUP #13: Alarm{1cf01cc type 0 origWhen 1756116000000 whenElapsed 531090820 com.android.settings}

tag=*walarm*:com.android.settings.battery.action.PERIODIC_JOB_UPDATE

type=RTC_WAKEUP origWhen=2025-08-25 18:00:00.000 window=0 exactAllowReason=policy_permission repeatInterval=0 count=0 flags=0x9

policyWhenElapsed: requester=+50m36s639ms app_standby=-2m25s208ms device_idle=-- battery_saver=--

whenElapsed=+50m36s639ms maxWhenElapsed=+50m36s639ms

operation=PendingIntent{7781c15: PendingIntentRecord{3f08b2a com.android.settings broadcastIntent}}

idle-options=Bundle[{android.pendingIntent.backgroundActivityAllowed=2, android:broadcast.temporaryAppAllowlistReasonCode=302, android:broadcast.temporaryAppAllowlistDuration=10000, android:broadcast.temporaryAppAllowlistReason=, android:broadcast.temporaryAppAllowlistType=0, android:broadcast.flags=8}]

类型 时间基准 设备电源状态 关键特性
RTC 日历时间 (UTC) 不唤醒 在指定北京时间 (或其他时区时间)触发,但会延迟到设备下次唤醒时执行。
RTC_WAKEUP 日历时间 (UTC) 唤醒 在指定北京时间 (或其他时区时间)触发,并立即唤醒设备执行。
ELAPSED 系统运行时间 不唤醒 在设备启动后的特定时间点 触发,但会延迟到设备下次唤醒时执行。
ELAPSED_WAKEUP 系统运行时间 唤醒 在设备启动后的特定时间点 触发,并立即唤醒设备执行。

十.LazyAlarmStore stats:

//LazyAlarmStore 性能统计

LazyAlarmStore stats:

//GET_NEXT_DELIVERY_TIME查询"下一个要交付(触发)的 alarm 的时间"的操作

//count 表示LazyAlarmStore.java::getNextDeliveryTime 函数执行的次数

//total 表示执行总次数

//avg 表示平均值(总时间除以总个数)

//max calls/s : 表示最大调用次数

//max dur/s :表示触发间隔超过1秒统计累计统计时间

//max time :表示单次最慢的调用耗时

GET_NEXT_DELIVERY_TIME: count=30699, total=70.6ms, avg=0.002ms, max calls/s=0 max dur/s=0.0ms max time=2.9ms

//GET_NEXT_WAKEUP_DELIVERY_TIME:下一个需要唤醒设备 (CPU从休眠中醒来)的 alarm 的时间

GET_NEXT_WAKEUP_DELIVERY_TIME: count=30699, total=343.9ms, avg=0.011ms, max calls/s=103 max dur/s=5.7ms max time=5.7ms

//GET_COUNT查询 alarm 数量的操作

// Android V 取消了次统计

GET_COUNT: count=0, total=0.0ms, avg=0.000ms, max calls/s=0 max dur/s=0.0ms max time=0.0ms

//没有因为用户操作(例如强制停止应用、限制后台活动等)而被系统拦截/阻塞的后台定时任务。

//是否存在app standby 拦截alarm

Pending user blocked background alarms:

none

//按用户 ID 分组的、当前 pending(等待触发)的 alarm 数量列表

// 譬如: uid 1000, 还有6个pending alarm

Pending alarms per uid: [1000:6, 1002:1, 1073:3, u0a61:1, u0a72:1, u0a128:1, u0a131:24, u0a133:2, u0a137:5]

十一. App Alarm history:

//通过app 统计已经触发的alarm

App Alarm history:

//5h34m9s220ms前触发过一次,com.google.android.googlequicksearchbox 触发过一次,用户是user0

com.google.android.googlequicksearchbox, u0 : -5h34m9s220ms,

com.android.providers.calendar, u0: -2h9m22s458ms,

com.google.android.apps.messaging, u0: -5h34m5s748ms,

com.google.android.configupdater, u0: -6d2h22m41s278ms,

//表示com.google.android.gms user0,在一小时内触发了8次,时间记录.

com.google.android.gms, u0: -2m16s388ms, -5m27s598ms, -5m33s73ms, -5m36s389ms, -5m37s150ms, -24m53s173ms, -34m28s149ms, -53m53s151ms,

com.google.android.calendar, u0: -16h0m35s100ms,

com.google.android.apps.wallpaper, u0: -2h9m23s362ms,

十二. Temporary Quota Reserves

//临时配额储备,没有打印表示为空

Temporary Quota Reserves:

//已过期 的"非唤醒"闹钟,数量为1

Past-due non-wakeup alarms: 1

//非唤醒闹钟详情

// 类型为:ELAPSED

ELAPSED #1: Alarm{5183fb3 type 3 origWhen 528030819 whenElapsed 528030819 android}

// tag 为alarm*:TIME_TICK

tag=*alarm*:TIME_TICK

//origWhen 表示本该23s362ms之前触发

//exactAllowReason 类型为allow-listed ,属于EXACT_ALLOW_REASON_ALLOW_LIST

type=ELAPSED origWhen=-23s362ms window=0 exactAllowReason=allow-listed

//repeatInterval 为0表示非重复alarm

//count为1,表示仅仅执行一次

//flags为0x9,在上面已经讲过.

repeatInterval=0 count=1 flags=0x9

policyWhenElapsed: requester=-23s362ms app_standby=-1m4s965ms device_idle=-- battery_saver=--

whenElapsed=-23s362ms maxWhenElapsed=-23s362ms

listener=com.android.server.alarm.AlarmManagerService$2@dea1e22

Number of delayed alarms: 2363, total delay time: +5d16h53m39s354ms

Max delay time: +59m58s958ms, max non-interactive time: +2d18h28m9s645ms

十三. Broadcast ref count

//正在投递中的alarm,当前值为0,说明没有正在处理的alarm

Broadcast ref count: 0

//自设备启动或统计重置以来,系统已经发送(触发)了 1267 次 PendingIntent

PendingIntent send count: 1267

//PendingIntent 已经完成处理1267 次

PendingIntent finish count: 1267

//不属于PendingIntent alarm ,直接使用Listener 有2016次

Listener send count: 2016

//Listener 处理完成2016 次

Listener finish count: 2016

//记录包含flag: FLAG_ALLOW_WHILE_IDLE的数据

// 调用setAndAllowWhileIdle/setExactAndAllowWhileIdle的统计

Allow while idle history:

//com.google.android.googlequicksearchbox 在user0, 6h9m22s152ms 之前调用过一次

com.google.android.googlequicksearchbox, u0: -6h9m22s152ms,

com.google.android.calendar, u0: -16h5m59s148ms,

//在doze或者batterySaver下触发alarm,进程一般在doze或者batterySaver 白名单中.

Allow while idle compat history:

com.google.android.gms, u0: -5m37s150ms,

十四. Removal history:

//移除历史alarm

Removal history:

//uid 为1000

1000:

//Reason:移除理由alarm_cancelled

//elapsed: 发生1m4s942ms 之前

//rtc 表示具体的时间

#1: Reason=alarm_cancelled elapsed=-1m4s942ms rtc=2025-08-25 17:08:18.419

//mAlarmSnapshot dump ,具体alarm 详情

Snapshot:

type=ELAPSED_WAKEUP tag=*walarm*:JS idleness

policyWhenElapsed: requester=+28m45s427ms app_standby=-2m14s572ms device_idle=-- battery_saver=--

#2: Reason=pi_cancelled elapsed=-2m25s258ms rtc=2025-08-25 17:06:58.103

Snapshot:

type=RTC_WAKEUP tag=*walarm*:com.android.settings.battery.action.PERIODIC_JOB_UPDATE

policyWhenElapsed: requester=+50m36s638ms app_standby=-24m52s840ms device_idle=-2m25s309ms battery_saver=--

1002:

#1: Reason=alarm_cancelled elapsed=-2m33s345ms rtc=2025-08-25 17:06:50.017

Snapshot:

type=ELAPSED_WAKEUP tag=*walarm*:com.android.bluetooth.gatt.REFRESH_BATCHED_SCAN

policyWhenElapsed: requester=+17m26s632ms app_standby=-2m33s366ms device_idle=-2m33s366ms battery_saver=--

#2: Reason=alarm_cancelled elapsed=-2m33s369ms rtc=2025-08-25 17:06:49.993

Snapshot:

type=ELAPSED_WAKEUP tag=*walarm*:com.android.bluetooth.gatt.REFRESH_BATCHED_SCAN

policyWhenElapsed: requester=+14m23s788ms app_standby=-5m36s207ms device_idle=-5m6s298ms battery_saver=--

十五. Top Alarms

// 获取前10个累计花费时间最长的TAG统计

Top Alarms:

//running:总运行时间:35s60ms

//wakeups:总唤醒次数

//1000:com.android.settings 对应的是广播的UID和对应的mPackageName

+35s60ms running, 145 wakeups, 145 alarms: 1000:com.android.settings

//mTag统计

*walarm*:com.android.settings.battery.action.PERIODIC_JOB_UPDATE

+28s820ms running, 79 wakeups, 79 alarms: 1000:android

*walarm*:android.appwidget.action.APPWIDGET_UPDATE

+28s756ms running, 0 wakeups, 112 alarms: u0a133:com.google.android.googlequicksearchbox

*alarm*:TIME TRIGGER ALLOW IDLE ACTION

+18s242ms running, 0 wakeups, 276 alarms: 1000:android

*alarm*:com.android.server.action.NETWORK_STATS_POLL

+13s866ms running, 0 wakeups, 674 alarms: 1000:android

*alarm*:TIME_TICK

+9s12ms running, 29 wakeups, 29 alarms: u0a61:com.android.providers.calendar

*walarm*:com.android.providers.calendar.intent.CalendarProvider2

+8s993ms running, 0 wakeups, 7 alarms: u0a72:com.google.android.apps.wallpaper

*alarm*:com.google.android.apps.wallpaper/com.android.wallpaper.module.DailyLoggingAlarmReceiver

+8s225ms running, 251 wakeups, 251 alarms: u0a131:com.google.android.gms

*walarm*:com.google.android.gms.gcm.HEARTBEAT_ALARM

+7s991ms running, 0 wakeups, 13 alarms: u0a133:com.google.android.googlequicksearchbox

*alarm*:com.google.android.libraries.notifications.SYSTEM_TRAY_EVENT

+5s779ms running, 0 wakeups, 298 alarms: 1000:android

*alarm*:*job.delay*

十六. Alarm Stats:

// alarm 统计

Alarm Stats:

//按照mBroadcastStats加入顺序遍历的

//1000:android 对应mUid:mPackageName

//+54s367ms 表示累计总运行时间.

//有579次唤醒

1000:android +54s367ms running, 579 wakeups:

//是根据tag 累计时间大小排序的

// *walarm*:android.appwidget.action.APPWIDGET_UPDATE 累计时长+28s820ms,有79次被唤醒,总设置的alarm 是79次.最近一次alarm触发是在22m53s111ms之前.

//walarm 表示带wakeup 的alarm

+28s820ms 79 wakes 79 alarms, last -22m53s111ms:

*walarm*:android.appwidget.action.APPWIDGET_UPDATE

+18s242ms 0 wakes 276 alarms, last -9m35s151ms:

*alarm*:com.android.server.action.NETWORK_STATS_POLL

+13s866ms 0 wakes 674 alarms, last -1m4s966ms:

*alarm*:TIME_TICK

+5s779ms 0 wakes 298 alarms, last -2m25s307ms:

十七. Alarm manager stats:

//alarm manager 统计

Alarm manager stats:

//是调用AlarmManagerService.java::reorderAlarmsBasedOnStandbyBuckets 函数的统计,根据app_standby 调整alarm 策略的数据

REORDER_ALARMS_FOR_STANDBY: count=2552, total=470.3ms, avg=0.184ms, max calls/s=399 max dur/s=13.0ms max time=7.0ms

//检查Manifest.permission.SCHEDULE_EXACT_ALARM 权限的统计

HAS_SCHEDULE_EXACT_ALARM: count=9748, total=494.7ms, avg=0.051ms, max calls/s=67 max dur/s=15.4ms max time=12.9ms

相关推荐
柯南二号7 小时前
【Android】【设计模式】抽象工厂模式改造弹窗组件必知必会
android·设计模式·抽象工厂模式
TsengOnce14 小时前
MySQL 性能调优与 SQL 优化的核心利器
android·sql·mysql
熊大与iOS14 小时前
iOS 长截图的完美实现方案 - 附Demo源码
android·算法·ios
独行soc15 小时前
2025年渗透测试面试题总结-42(题目+回答)
android·数据库·安全·adb·面试·渗透测试·sqlite
千里马学框架17 小时前
安卓15 audio新专题发布:安卓系统手机车机音频audio子系统深入实战开发专题
android·智能手机·音视频
没有了遇见17 小时前
Android 虚拟环境之虚拟环境检测<完结版>
android
liang_jy17 小时前
Android 单元测试(二)—— 高级 Mock 技术
android·面试·单元测试
liang_jy18 小时前
Android 单元测试(一)—— 基础
android·面试·单元测试