2011-05-07 84 views
20

pmkeepScreenOn变量是全局定义的。WakeLock完成时仍然保留

我抢PowerManager.WakeLock在我的onCreate方法:

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 compl AINS是

java.lang.Exception的:唤醒锁定最终确定,同时还举行:TPD

跟踪显示,我发布退出前锁。 我错过了什么?

没有穿越至少有一个 ,onStoponDestroy没有出路的应用程序。我可以看到,该应用程序通常称为acquire(),因此即使 wakelock是引用计数,它仍应具有零引用。

+0

可能与您的问题无关,但您为什么要在这么多地方创建和释放锁?为什么不只在onResume和onPause? – Olegas 2011-05-07 14:23:45

+0

我试过了。然后我跟踪了每个XXX例程。然后我添加了它 – 2011-05-07 15:42:08

+0

您的'keepScreenOn'变量在类中只声明过一次吗?是否有一些其他声明的范围较小(即在方法中声明)。 – Olegas 2011-05-07 17:47:42

回答

0

不,全局范围内只有一个声明,并且所有对acquire()和release()的调用都发生在该范围内。当它们发生并且获取()发生一次并且 释放发生一次时。

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会引发错误。

相关问题