2011-05-07 39 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會引發錯誤。

相關問題