WakeLock仍然在最后定案

pmkeepScreenOnvariables是全局定义的。

我在我的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

跟踪显示我在退出之前释放了锁。 我错过了什么?

没有穿越onPauseonStoponDestroy至less一个,没有办法离开应用程序。 我可以看到,应用程序调用了release() ,就像它调用acquire()一样,即使wakelock是引用计数,它仍然应该有零引用。

好吧,我相信我发现了这个问题。

WakeLock是参考计数。 这意味着如果发生第二次acquire() ,它将会引起参考计数。 每次调用acquire()需要通过调用isHeld()来保护,如下所示:

 if ((keepScreenOn != null) && // we have a WakeLock (keepScreenOn.isHeld() == false)) { // but we don't hold it keepScreenOn.acquire(); } 

我曾经假定,在我locking的锁acquire()上没有做任何事情,所以多次acquire()调用导致了这个问题。 由于引用计数不为零,GC会引发错误。

我知道这个问题是旧的,但请记住,默认情况下,WakeLocks是“引用计数”。 您可以使用setReferenceCounted(boolean)closures引用计数,请参阅http://developer.android.com/reference/android/os/PowerManager.WakeLock.html#setReferenceCounted(boolean)

不,在全局范围内只有一个声明,所有对acquire()和release()的调用都发生在该范围内。 我println,当他们发生和获得()发生一次,释放发生一次。