WakeLock 在仍持有时完成
pm
和 keepScreenOn
变量是全局定义的。
我在 OnCreate 方法中获取 PowerManager.WakeLock:
pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
keepScreenOn = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_LOCK,"tpd");
在 onStart、onResume 和 onRestart 中,我在 onDestroy、onPause 和 onStop 中获取锁
if (keepScreenOn == null) {
keepScreenOn = pm.newakeLock(PowerManager,SCREEN_BRIGHT_LOCK,"tpd");
}
keepScreenOn.acquire();
,然后释放锁:
if (keepScreenOn != null) {
keepScreenOn.release();
keepScreenOn = null
}
在我的应用程序退出后,出现故障屏幕并且 adb 抱怨那
java.lang.Exception:WakeLock 在仍持有时完成:tpd
跟踪显示我在退出之前释放了锁。 我错过了什么?
如果不跨越至少一个,就无法退出该应用程序 onPause
、onStop
或 onDestroy
。我可以看到该应用程序名为 release()
和调用 acquire() 一样频繁,所以即使 唤醒锁是引用计数的,它应该仍然有零引用。
The pm
and keepScreenOn
variables are globally defined.
I grab the PowerManager.WakeLock in my OnCreate method:
pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
keepScreenOn = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_LOCK,"tpd");
in my onStart, onResume, and onRestart I grab the lock with
if (keepScreenOn == null) {
keepScreenOn = pm.newakeLock(PowerManager,SCREEN_BRIGHT_LOCK,"tpd");
}
keepScreenOn.acquire();
in my onDestroy, onPause, and onStop I release the lock with:
if (keepScreenOn != null) {
keepScreenOn.release();
keepScreenOn = null
}
After my app exits I get a failure screen and adb complains that
java.lang.Exception: WakeLock finalized while still held: tpd
Tracing shows that I released the lock before exit.
What have I missed?
There is no way out of the app without crossing at least one ofonPause
, onStop
, or onDestroy
. I can see that the app calledrelease()
as often as it called acquire() so even though the
wakelock is reference counted it should still have zero refs.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
好吧,我相信我找到了问题。
WakeLock 是引用计数的。这意味着如果第二个
acquire()
发生这种情况只会增加引用计数。每次调用
acquire()
需要通过调用
isHeld()
进行保护,如下所示:我假设我持有的锁上的
acquire()
没有执行任何操作,因此多次
acquire()
调用导致了该问题。自从参考count 不为零,GC 会抛出错误。
Ok I believe I found the problem.
The WakeLock is reference counted. That means that if a second
acquire()
happens it will just bump the reference count. Every call to
acquire()
needs to be protected by a call to
isHeld()
as in:I had assumed that
acquire()
on a lock I held did nothing somultiple
acquire()
calls caused the problem. Since the referencecount is not zero the GC throws an error.
我知道这个问题很老了,但请记住,WakeLocks 默认情况下是“引用计数”的。您可以使用
setReferenceCounted(boolean)
关闭引用计数,请参阅 http://developer.android.com/reference/android/os/PowerManager.WakeLock.html#setReferenceCounted(boolean)I know this question is old, but keep in mind that WakeLocks are 'reference counted' by default. You can turn off reference counting using
setReferenceCounted(boolean)
, see http://developer.android.com/reference/android/os/PowerManager.WakeLock.html#setReferenceCounted(boolean)不,全局范围内只有一个声明,并且所有
对 acquire() 和 release() 的调用发生在该范围内。我
println 当它们发生时并且 acquire() 发生一次并且
释放发生一次。
No, there is only one declaration at the global scope and all
calls to the acquire() and release() occur in that scope. I
println when they happen and the acquire() occurs once and the
release occurs once.