Подтвердить что ты не робот

WakeLock завершил работу еще

Переменные pm и keepScreenOn определяются глобально.

Я захватил 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 жалуется, что

java.lang.Exception: WakeLock финализирован, но все еще сохранен: tpd

Трассировка показывает, что я выпустил блокировку перед выходом. Что я пропустил?

Невозможно выйти из приложения, не пересекая хотя бы одну из onPause, onStop или onDestroy. Я вижу, что приложение называется release() так часто, как он называется gets(), так что хотя wakelock ссылается на ссылку, он должен по-прежнему иметь нулевые ссылки.

4b9b3361

Ответ 1

Хорошо, я считаю, что нашел проблему.

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 генерирует ошибку.

Ответ 3

Нет, в глобальном масштабе есть только одно объявление и все вызовы для получения() и release() происходят в этой области. я println, когда они происходят, и метод получения() происходит один раз, а релиз происходит один раз.