pm
和keepScreenOn
变量是全局定义的。
我在OnCreate方法中获取了PowerManager.WakeLock:
pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
keepScreenOn = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_LOCK,"tpd");
在我的onStart,onResume和onRestart中,我用
抓住了锁if (keepScreenOn == null) {
keepScreenOn = pm.newakeLock(PowerManager,SCREEN_BRIGHT_LOCK,"tpd");
}
keepScreenOn.acquire();
在我的onDestroy,onPause和onStop中,我用以下内容释放锁:
if (keepScreenOn != null) {
keepScreenOn.release();
keepScreenOn = null
}
我的应用退出后,我收到了失败的屏幕,adb抱怨
java.lang.Exception:WakeLock在仍然持有时完成:tpd
跟踪显示我在退出前释放了锁。 我错过了什么?
没有穿越至少一个应用程序,没有办法退出应用程序
onPause
,onStop
或onDestroy
。我可以看到应用程序调用
release()
经常称为acquire(),即使是
wakelock是参考计数它应该仍然有零参考。
答案 0 :(得分:27)
好的我相信我发现了问题。
WakeLock是引用计数。这意味着,如果第二个acquire()
碰巧它只会碰到引用计数。每次拨打acquire()
需要通过调用isHeld()
来保护,如:
if ((keepScreenOn != null) && // we have a WakeLock
(keepScreenOn.isHeld() == false)) { // but we don't hold it
keepScreenOn.acquire();
}
我原以为acquire()
对我所持有的锁没做任何事情
多个acquire()
来电导致了这个问题。自参考
计数不为零,GC会抛出错误。
答案 1 :(得分:3)
我知道这个问题已经过时了,但请记住,默认情况下,WakeLocks是“引用计数”。您可以使用setReferenceCounted(boolean)
关闭引用计数,请参阅http://developer.android.com/reference/android/os/PowerManager.WakeLock.html#setReferenceCounted(boolean)
答案 2 :(得分:0)
不,全球范围内只有一个声明 在该范围内发生对acquire()和release()的调用。一世 println当它们发生并且acquire()发生一次并且 释放一次。