pmkeepScreenOn变量是全局定义的。

我在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提示



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

没有跨越以下任何一项,就无法退出应用程序onPauseonStoponDestroy。我可以看到该应用程序调用了release()的调用频率与它的generate()相同,因此即使
唤醒锁是引用计数的,它仍应具有零个引用。

最佳答案

好吧,我相信我找到了问题。

WakeLock被引用计数。这意味着如果第二个acquire()碰巧会碰到引用计数。每次调用acquire()需要通过调用isHeld()进行保护,如下所示:

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

我以为我持有的锁上的acquire()没有任何作用,所以
多次acquire()调用导致了此问题。自引用
count不为零GC会引发错误。

09-25 23:20