Android* 的唤醒锁

WakeLock_WhitePaper.doc
BSD2.0.txt
WakeLock.zip

Christopher Bird

Android 电源管理 — 唤醒锁全新上市

大多数人可能都遭遇过手机的电池续航时间较短带来的尴尬。 这极其令人讨厌。 没电的手机和一块水泥砖没什么差别。 一般而言,如果用户的手机电池无法持续一整天,他们会感到非常不满。而且,当手机充电时用户无法使用手机,这同样会带来极大的不便。

传统上需要使用笔记本电脑或 PC 处理的任务,现在借助全新的改进软件,即使未在桌旁也可使用智能手机进行处理。 但是相比笔记本电脑,智能手机的小外形很大地限制了可容纳的电池尺寸。 既要求手机具备笔记本电脑的功能,同时又要求其具备全天候的电池续航能力是难以实现的。

通过采用出色的电源管理,Android 和其他移动操作系统实现了耐久的电池续航时间。 停止使用手机后不久,显示器便会关闭,CPU 会进入深度节能状态,因此在不使用它时仅会消耗极少的电源。 这就是电话在使用时充一次电便能持续使用多日的原因。 借助 Android 的电源管理器,正常计划是显示器关闭时 CPU 也关闭。

但是,Android 开发人员能够(并有权限)阻止 Android 设备进入睡眠模式。 他们可能希望让 CPU 处于活动状态 — 即使显示器关闭。 或者可能他们希望在执行某项活动时阻止显示器自动关闭。 出于此原因,Google* 在其 PowerManager API 中增加了唤醒锁。 阻止设备进入睡眠模式的应用可以使用唤醒锁。 只要系统上有活动的唤醒锁,设备便无法进入挂起模式,除非释放唤醒锁。 使用唤醒锁时,一定要了解到当您不需要唤醒锁时,必须将其正确释放,因为未释放的唤醒锁无法进入默认状态以节能,从而很快便会将设备的电池耗尽。

本文将会为您介绍一些在 Android 4.0 中默认使用唤醒锁的 Android 应用(和使用模式),以便帮助您了解何时使用此项技术。 然后,将会介绍一个 SDPSamples 集中的示例应用“Wakelocks”,以展示如何编写唤醒锁的代码。

唤醒锁应用使用情况

借助 Android, 有一种方法可以查看哪些服务启用了唤醒锁,阻止系统进入低功耗状态。 设备上的 /proc/wakelocks 文件列出了定义使用唤醒锁的服务和驱动程序。 通过监控 /sys/power/wake_lock 文件的内容(需要根访问),您可以了解 CPU 资源何时启用了唤醒锁,以及哪种服务启用了 wakelock2。 我捕获了几种使用案例,其中运行 Android 4.0 的 Galaxy Nexus 上启用了唤醒锁,如下所示:

使用的应用 执行的操作 使用了唤醒锁的服务 运行状况
任意 按下 UI Widget(如点击按钮或 ListView 项) PowerManagerService 启用并在 5 秒钟后释放锁定
地图/导航 启用地图或进入导航 gps-lock 启用锁定并使用 GPS
YouTube 观看流视频 PowerManagerService 在视频播放的整个过程中一直启用唤醒锁
Music 听音乐 PowerManagerService 在音乐播放的过程中一直启用唤醒锁

表格:一些默认的 Android 应用演示唤醒锁的使用

YouTube 和 Music 应用能够很好地展示不同级别的唤醒锁。 用户播放视频时,YouTube 应用将会启用唤醒锁。 在播放视频的整个过程中,显示器会保持开启状态(忽略系统的显示设置)。 但是,如果用户在播放过程中按下了电源按钮,设备将会挂起,这会导致显示器关闭以及音频/视频停止播放。 Music 应用在播放音频时使用不同的唤醒锁。 显示设置无法更改,因此设备的屏幕将会根据用户的显示设置来关闭。 显示器关闭后,唤醒锁会让 CPU 保持活动状态以便音频能够继续播放 — 即使用户按下了电源按钮。

选择唤醒锁(在执行前)

在了解如何编写唤醒锁之前,一定要了解唤醒锁的种类,以便为您的应用挑选最适合的唤醒锁。 Android PowerManager API 介绍了多种用于更改设备电源状态的唤醒锁标记:

标记值 CPU 屏幕 键盘
PARTIAL_WAKE_LOCK 开启 关闭 关闭
SCREEN_DIM_WAKE_LOCK 开启 调暗(Dim) 关闭
SCREEN_BRIGHT_WAKE_LOCK 开启 调亮(Bright) 关闭
FULL_WAKE_LOCK 开启 调亮(Bright) 调亮(Bright)

表格: 源自 Android PowerManager API。

该 API 突出强调了唤醒锁会显著缩短 Android 设备的电池续航时间,因此如果可以避免应尽量减少使用它们。 如果使用,也应尽快将其释放。

使用唤醒锁的应用必须申请特别许可才可执行。 这可通过应用清单文件中的 android.permission.WAKE_LOCK 许可来实现。 也就是说,当用户通过 Google Play 安装使用唤醒锁的应用时,系统会提醒他们该应用包含的特性可能会“Prevent phone from sleeping(阻止手机进入睡眠状态)”。 如果开发人员希望阻止某个应用的显示器在特定使用情况下变暗,可采用 Google 另外提供的一种方法,这种方法无需特别许可。 WindowManager 包括一个 FLAG_KEEP_SCREEN_ON 变量,当应用的视图要阻止界面关闭时可对其进行设置。 建议在显示控制上使用这种方法,因为其影响在应用内相互独立。 用户任务切换到其他应用上之后,WindowManager 将会立刻释放唤醒锁。

让显示器保持开启状态(源自 SDPSamples)

SDPSamples 集的唤醒锁应用演示了(包括代码)应用如何使用 Window Manager 而非通过编写唤醒锁代码让显示器保持开启状态。 启用唤醒锁应用后,选择“Win Man Screen On”列表项。

只要按钮的状态显示“Screen is LOCKED”,界面就会保持开启状态。 按钮的状态更改为“Screen is UNLOCKED”后,如果超过 5 秒钟不操作,显示器将会关闭。

在代码中,每次按下按钮且状态发生改变时,通过设置和释放当前窗口的 FLAG_KEEP_SCREEN_ON 变量可在 WakeLockActivity.java 中使用 screenLockUpdateState() 函数实现该操作。

public void screenLockUpdateState() {

    if (mIsDisplayLocked)
     {
        ...
        // update display state
      getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    } else 
{
        ...
        // update display state
          getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    }
} 

编写唤醒锁(来自 SDPSamples)

SDPSamples 集中的唤醒锁应用还包括执行不同唤醒锁的代码。 启动唤醒锁应用后,从下列四种唤醒锁中选择: Power Wake Lock Full、Power Wake Lock Bright、Power Wake Lock Dim 和 Power Wake Lock Partial。 这 4 个列表项对应着 PowerManager API 中介绍的 4 种唤醒锁标记。 每一项将会分别演示 5 秒内尝试关闭屏幕时设备如何响应。

通过监控 /sys/power/wake_lock 文件的内容(需要根访问),您可以看到按下电源按钮后 PARTIAL_WAKE_LOCK 是唯一仍然有效的唤醒锁。 其他的唤醒锁通过多种级别的亮度阻止显示器关闭。

编写唤醒锁的第一步是申请许可,之后才可使用清单 AndroidManifest.xml 内的唤醒锁:

这一步完成后,便可以创建唤醒锁对象,包括控制唤醒锁的获取()函数和释放()函数。 WakeLockActivity.java 文件内的编码很好地展示了该情况:

public void onCreate(Bundle savedInstanceState) {
    ...
    mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
    ...
    mWakeLock = mPowerManager.newWakeLock(mWakeLockState,
						"UMSE PowerTest");
    if (mWakeLock != null) {
        mWakeLock.acquire();
    ...	
    }
}

protected void onDestroy() {
    if (mWakeLock != null) {
        mWakeLock.release();
        mWakeLock = null;
    }
    ...	
}

结论

唤醒锁是 Android 中一款强大的概念,可支持开发人员修改设备的默认电源状态。 在应用中使用唤醒锁的风险:它会减少设备的电池续航时间。 使用唤醒锁的明显优点可在 Google 提供的多种默认应用中看得到,如道路导航和音乐/视频播放。 因此,开发人员应自行确定他们的应用模型能否从使用唤醒锁中得益。

关于作者

Christopher Bird 于 2007 年进入英特尔的 SSG,致力于构建支持凌动设备(手机和平板电脑)的生态系统

参考

1 Android 参考: http://developer.android.com/reference/android/os/PowerManager.html

2 LWN – “唤醒锁和嵌入式问题”: http://lwn.net/Articles/318611/

声明

本文件中包含关于英特尔产品的信息。 本文件不构成对任何知识产权的授权,包括明示的、暗示的,也无论是基于禁止反言的原则或其他。 英特尔不承担任何其他责任。英特尔在此作出免责声明:本文件不构成英特尔关于其产品的使用和/或销售的任何明示或暗示的保证,包括不就其产品的(i)对某一特定用途的适用性、(ii)适销性以及(iii)对任何专利、版权或其他知识产权的侵害的承担任何责任或作出任何担保。

除非经过英特尔的书面同意认可,英特尔的产品无意被设计用于或被用于以下应用:即在这样的应用中可因英特尔产品的故障而导致人身伤亡。

英特尔有权随时更改产品的规格和描述而毋需发出通知。 设计者不应信赖任何英特产品所不具有的特性,设计者亦不应信赖任何标有“保留权利”或“未定义”的说明或特性描述。 对此,英特尔保留将来对其进行定义的权利,同时,英特尔不应为因其日后更改该等说明或特性描述而产生的冲突和不相容承担任何责任。 本文信息可能随时更改,恕不另行通知。 请勿使用本文信息完成一项产品设计。


本文件所描述的产品可能包含使其与宣称的规格不符的设计缺陷或失误。 这些缺陷或失误已收录于勘误表中,可索取获得。 在发出订单之前,请联系当地的英特尔营业部或分销商以获取最新的产品规格。

索取本文件中或英特尔的其他材料中提的、包含订单号的文件的复印件,可拨打1-800-548-4725,或登陆 http://www.intel.com/design/literature.htm

性能测试中使用的软件和工作负载可能仅在英特尔微处理器上针对性能进行了优化。 诸如 SYSmark 和 MobileMark 等测试均系基于特定计算机系统、硬件、软件、操作系统及功能。 上述任何要素的变动都有可能导致测试结果的变化。 请参考其他信息及性能测试(包括结合其他产品使用时的运行性能)以对目标产品进行全面评估。

对本文件中包含的软件源代码的提供均依据相关软件许可而做出,任何对该等源代码的使用和复制均应按照相关软件许可的条款执行。

英特尔和 Intel 标识是英特尔在美国和/或其他国家的商标。

英特尔公司 © 2012 年版权所有。 所有权利受到保护。

*其他的名称和品牌可能是其他所有者的资产。