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 ссылается на ссылку, он должен по-прежнему иметь нулевые ссылки.
Ответы
Ответ 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 генерирует ошибку.
Ответ 2
Я знаю, что этот вопрос старый, но имейте в виду, что WakeLocks по умолчанию считается ссылкой. Вы можете отключить подсчет ссылок с помощью setReferenceCounted(boolean)
, см. http://developer.android.com/reference/android/os/PowerManager.WakeLock.html#setReferenceCounted(boolean)
Ответ 3
Нет, в глобальном масштабе есть только одно объявление и все
вызовы для получения() и release() происходят в этой области. я
println, когда они происходят, и метод получения() происходит один раз, а
релиз происходит один раз.