4

我知道最好的做法wake_lock是在不再需要 a 时立即释放它,但是如果Activityor Service,例如,在释放锁之前已经完成或停止,会发生什么情况?是系统自动释放的吗?我认为在这种情况下系统应该自动释放它们,但我在 API 文档上找不到任何东西。

编辑:添加了更多信息

查看PowerManager.WakeLock文档,我看到默认情况下,wake_locks 是引用计数的(setReferenceCounted 在此处阅读),即如果我们在活动中检索唤醒锁,PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "myWakeLock"); wl.acquire();然后wl保存它的引用变量超出范围,那么唤醒锁被释放是因为它的引用计数变为零……对吗?

编辑:上面的错误理解

我想我误解了上面的引用计数概念......它应该意味着如果我获得两次锁并只释放一次,那么引用计数为1并且尚未释放锁。如果它没有被引用计数,那么我可以获取 x 次,然后通过一次释放它被释放。

4

4 回答 4

2

网络上似乎有很多关于此的错误信息。在 Android API 中公开的 WakeLock 有一个相当复杂的生命周期,除了超级勤奋地管理它之外,真的没有别的办法。

如果活动或服务在您没有释放唤醒锁的情况下停止,则状态未定义。如果您检查代码(https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/os/PowerManager.java,搜索“class WakeLock”),您会看到它们当它们被垃圾收集时被释放。

然而,“当它们被垃圾收集时”是一个非常松散的陈述。在实践中,Lollipop 之前的设备似乎对唤醒锁的 GC 非常慢(出于实际目的,我们可以假装它根本没有发生),但是在具有 ART 运行时的 post-Lollipop 设备上,流浪的 WakeLock 似乎是在一个几秒钟。

关于引用计数的问题,您可以在 Android 代码中看到锁被释放,而不管它有多少计数。

如果你把责任归咎于 Android 代码,你还可以看到这些年来它并没有太大变化——所以这一切都归结为 GC 的行为方式。因此,您需要勤奋,将锁存储在您的活动/服务的字段中,并在应用程序生命周期的合理位置释放/获取。但是,如果可能的话,您不应该使用唤醒锁,而应该使用 Gatekeeper 在其他答案之一中链接到的 Force Screen On 技巧。

于 2015-08-07T07:15:40.457 回答
1

只有当进程被销毁时,唤醒锁才会被释放。只是通过完成服务/活动wake_lock不会被释放。

于 2012-08-26T15:28:51.787 回答
0

我相信这个答案将帮助您实现跨越式强制屏幕打开

PowerManager API 声明您应该尽快释放唤醒锁,众所周知,使用 PowerManager API 会消耗更多电池。同样在它的 API 中它指出:

*如果您持有部分唤醒锁,CPU 将继续运行,不管任何定时器,甚至在用户按下电源按钮后。在所有其他唤醒锁中,CPU 将运行,但用户仍然可以使用电源按钮使设备进入睡眠状态。

http://developer.android.com/reference/android/os/PowerManager.html

于 2012-08-26T15:29:35.287 回答
0

this answer中所述,如果进程被杀死,那么是的,唤醒锁被释放。但是,如果服务或活动正常完成而没有发布,答案应该是否定的。

于 2013-07-05T21:15:22.697 回答