wakefulbroadcastreceiver studio keep developer android android-activity wakelock

android - studio - wakefulbroadcastreceiver



WakeLock finalizó mientras aún se mantiene (3)

No, solo hay una declaración en el ámbito global y todas las llamadas a adquirir () y release () ocurren en ese ámbito. Imprimo cuando suceden y la adquisición () se produce una vez y el lanzamiento se produce una vez.

Las variables pm y keepScreenOn están definidas globalmente.

Agarro el PowerManager.WakeLock en mi método OnCreate:

pm = (PowerManager) getSystemService(Context.POWER_SERVICE); keepScreenOn = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_LOCK,"tpd");

en mi onStart, onResume y onRestart tomo el bloqueo con

if (keepScreenOn == null) { keepScreenOn = pm.newakeLock(PowerManager,SCREEN_BRIGHT_LOCK,"tpd"); } keepScreenOn.acquire();

en mi onDestroy, onPause y onStop libero el bloqueo con:

if (keepScreenOn != null) { keepScreenOn.release(); keepScreenOn = null }

Después de que mi aplicación salga, aparece una pantalla de error y adb se queja de que

java.lang.Exception: WakeLock finalizó mientras aún se mantiene: tpd

El rastreo muestra que liberé el bloqueo antes de salir. ¿Qué me he perdido?

No hay forma de salir de la aplicación sin cruzar al menos uno de onPause , onStop o onDestroy . Puedo ver que la aplicación se llama release() con la frecuencia con la que se llama adquirir (), por lo que a pesar de que el wakelock es una referencia contada, debería tener cero refs.


Ok, creo que encontré el problema.

El WakeLock es referencia contada. Eso significa que si ocurre una segunda acquire() , solo aumentará el conteo de referencia. Cada llamada para acquire() debe estar protegida por una llamada a isHeld() como en:

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

Yo había asumido que acquire() en un bloqueo que tenía no hacía nada, por lo que múltiples llamadas de acquire() causaban el problema. Dado que el recuento de referencia no es cero, el GC emite un error.