多个库和系统 API 可能会获取可归因于您应用的唤醒锁。这可能会导致难以识别应用中可能导致问题的唤醒锁。如果您误用某个 API,可能会导致您的应用持有唤醒锁的时间过长,即使您并未直接调用唤醒锁 API 也是如此。
本文档列出了一些在使用唤醒锁定调试工具时可能会看到的常见唤醒锁定名称。您还可能会在 Android Vitals 的报告中看到这些名称。在某些情况下,唤醒锁定可能由库或系统 API 创建。在其他情况下,该工具会混淆您在应用中使用的唤醒锁定名称是有原因的。您可以使用调试工具来识别行为不当的唤醒锁定,然后在本文档中搜索该唤醒锁定名称,以确定哪个 API 可能会导致问题以及如何解决该问题。
本文档介绍了可能会创建唤醒锁的场景。在每种情况下,虽然唤醒锁定可能由其他库或 API 创建,但该锁定会归因于调用相应 API 的应用。
AlarmManager
- 音频和媒体
- Firebase Cloud Message (FCM)
- JobScheduler
- 位置信息
- WorkManager
_UNKNOWN
:如果唤醒锁名称似乎使用了个人身份信息 (PII),调试工具会显示此消息。
AlarmManager
AlarmManager
会获取唤醒锁定并将其归因于调用应用。当闹钟响起时,AlarmManager
会获取唤醒锁定,并在闹钟广播的 onReceive()
方法执行完毕时释放锁定。
唤醒锁定名称
AlarmManager
创建名为 *alarm*
的唤醒锁。(星号是唤醒锁名称的一部分,不代表通配符。)
建议
我们建议您采取以下做法来优化闹钟行为:
- 使用
AlarmManager
优化闹钟调度频率。 - 仅在必要时使用
RTC_WAKEUP
闹钟(会唤醒设备)。 - 尽量减少使用闹钟,并避免在
onReceive()
方法中执行长时间运行的任务。
音频和媒体
媒体 API 在录制或播放音频时可以获取唤醒锁定。 唤醒锁定归因于调用方应用。
唤醒锁定名称
媒体 API 会获取以 Audio
开头的各种名称的唤醒锁定:
AudioBitPerfect
:用于无损 USB 音频播放。AudioDirectOut
:用于在电视或特殊设备上播放无损音频。AudioDup
:用于在通过蓝牙或 USB 连接时播放通知。AudioIn
:在摄像机模式下麦克风处于活动状态时,用于音频捕获。AudioMix
:用于将音频播放到通用设备。AudioOffload
:用于长时间的纯音乐播放,适用于支持此模式的应用。AudioSpatial
:用于在支持空间音频的设备上播放多声道电影或音乐音频。AudioUnknown
:当其他情况均不适用时使用。MmapCapture
:用于低延迟音频捕获。MmapPlayback
:用于低延迟播放,例如游戏或专业音频应用。
建议
我们建议您采取以下做法:
- 请勿使用以
Audio
开头的唤醒锁定名称。 - 如果您使用的是媒体 API,则无需直接获取唤醒锁;您可以依靠这些 API 为您获取必要的唤醒锁。
- 使用媒体 API 时,当不再需要媒体会话时,请结束该会话。
Firebase Cloud Message (FCM)
GCM 在向应用传送 Firebase 云消息传递 (FCM) 广播时会获取唤醒锁定。一旦 FCM 广播的 onMessageReceived()
方法执行完毕,唤醒锁定就会释放。
唤醒锁定名称
GCM 会获取名为 GOOGLE_C2DM
的唤醒锁定。
建议
我们建议您采取以下做法来优化 FCM 行为:
- 优化 FCM 传送频率。
- 除非消息确实需要立即传递,否则请勿使用高优先级 FCM。
- 尽快完成
onMessageReceived()
方法。 如需了解详情,请参阅 Firebase 指南。
JobScheduler
JobScheduler 作业在后台执行任务时会获取唤醒锁定。唤醒锁定归因于创建工作线程的应用。
唤醒锁定名称
JobScheduler 获取的唤醒锁名称取决于其运行的 Android 系统版本以及作业的用途。
尖括号中的项是变量。例如,“<package_name>”是应用的软件包名称,而不是字面文本 <package name>
。不过,*job*
是包含星号的字符序列 *job*
;星号并非用作通配符。
Android 15 及更低版本
用户发起的作业会创建遵循以下模式的唤醒锁:
*job*u/@<name_space>@/<package_name>/<classname>
其他作业使用此模式:
*job*/@<name_space>@/<package_name>/<classname>
Android 16 及更高版本
用户发起的作业会创建遵循以下模式的唤醒锁定:
*job*u/@<name_space>@/#<trace_tag>#/<package_name>/<classname>
加急作业使用以下模式:
*job*e/@<name_space>@/#<trace_tag>#/<package_name>/<classname>
常规作业使用以下模式:
*job*r/@<name_space>@/#<trace_tag>#/<package_name>/<classname>
示例
假设有一个命名空间为 backup
且轨迹标记为 started
的加急作业。软件包名称为 com.example.app
,创建作业的类为 com.backup.BackupFileService
。
在搭载 Android 15 或更低版本的设备上,唤醒锁的名称为:
*job*/@backup@/com.example.app/com.backup.BackupFileService
在搭载 Android 16 或更高版本的设备上,唤醒锁的名称为:
*job*e/@backup@/#started#/com.example.app/com.backup.BackupFileService
建议
审核您对 JobScheduler 任务的使用情况。请特别遵循我们有关优化任务调度 API 的电池使用情况的指南。
位置
LocationManager
和 FusedLocationProviderClient
使用唤醒锁定来获取和传递设备位置信息。唤醒锁归因于调用这些 API 的应用。
唤醒锁定名称
位置信息服务使用以下名称:
CollectionLib-SigCollector
NetworkLocationLocator
NetworkLocationScanner
NlpCollectorWakeLock
NlpWakeLock
*location*
建议
优化位置信息使用。例如,设置超时时间、批量处理位置信息请求或使用被动位置信息更新。
WorkManager
WorkManager worker 在后台执行任务时会获取唤醒锁定。唤醒锁定归因于创建工作线程的应用。
唤醒锁定名称
WorkManager 获取的唤醒锁名称取决于其运行的 Android 系统版本。
Android 15 及更低版本
WorkManager 任务会创建遵循以下模式的唤醒锁:
*job*/<package_name>/androidx.work.impl.background.systemjob.SystemJobService
Android 16 及更高版本
加急任务会创建名称遵循以下格式的唤醒锁定:
*job*e/#<trace_tag>#/<package_name>/androidx.work.impl.background.systemjob.SystemJobService
常规任务遵循以下模式:
*job*r/#<trace_tag>#/<package_name>/androidx.work.impl.background.systemjob.SystemJobService
默认情况下,<trace_tag>
是工作器的名称。
示例
假设有一个名为 BackupFileWorker
的加急工作器。软件包名称为 com.example.app
。
在搭载 Android 15 或更低版本的设备上,唤醒锁的名称为:
*job*/com.example.app/androidx.work.impl.background.systemjob.SystemJobService
在搭载 Android 16 或更高版本的设备上,唤醒锁的名称为:
*job*e/#BackupFileWorker#/com.example.app/androidx.work.impl.background.systemjob.SystemJobService
建议
审核 WorkManager 工作器的使用情况。请特别遵循我们有关优化任务调度 API 的电池使用情况的指南。
_UNKNOWN
如果调试工具认为唤醒锁定名称包含个人身份信息 (PII),则不会显示实际的唤醒锁定名称。而是将唤醒锁定标记为 _UNKNOWN
。例如,如果唤醒锁名称包含电子邮件地址,工具可能会执行此操作。
建议
遵循唤醒锁定命名最佳实践,避免在唤醒锁定名称中使用 PII。如果您发现归因于应用的唤醒锁定名为 _UNKNOWN
,请尝试确定该唤醒锁定,并为其指定其他名称。