WakeLock finalisés toujours détenus
La pm
et keepScreenOn
variables sont globalement définies.
Je prends la PowerManager.WakeLock dans ma méthode OnCreate:
pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
keepScreenOn = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_LOCK,"tpd");
dans mon onStart, onResume, et onRestart je prends la serrure avec
if (keepScreenOn == null) {
keepScreenOn = pm.newakeLock(PowerManager,SCREEN_BRIGHT_LOCK,"tpd");
}
keepScreenOn.acquire();
dans mon onDestroy, onPause, et onStop je libère le verrou avec:
if (keepScreenOn != null) {
keepScreenOn.release();
keepScreenOn = null
}
Après mon appli quitte-je obtenir une défaillance de l'écran et de la bad se plaint que
java.lang.Exception: WakeLock finalisés encore lieu: dpt
Traçage montre que j'ai sorti le verrou avant de quitter.
Qu'ai-je manqué?
Il n'y a aucun moyen de sortir de l'application, sans les croiser au moins un de
onPause
, onStop
, ou onDestroy
. Je peux voir que l'application appelée
release()
aussi souvent qu'il l'appelle acquérir (), donc même si l'
wakelock de référence est comptée, il doit quand même avoir zéro réf.
- Peut-être il n'est pas lié à ton problème, mais pourquoi de la création et de libérer de verrouillage dans de nombreux endroits? Pourquoi ne pas le faire seulement à onResume et onPause?
- J'ai essayé aussi. Puis j'ai tracé tous les onXXX routine. Puis je l'ai ajouté
- Est votre
keepScreenOn
variable est déclarée qu'une seule fois dans une classe? Est-il des autres déclarations de moindre portée (déclarée dans la méthode). - J'ai tendance à utiliser
WakeLock.acquire(5000)
, où 5 000 un délai d'attente, ou un autre délai que vous le souhaitez. Cette méthode semble fonctionner de manière cohérente. Alors queWakeLock.acquire()
sans un délai d'attente de façon inattendue peut conduire à des WakeLock finalisés encore tenues. C'est un hit-and-miss de l'affaire. Si vous ne voulez pas écrire votre propre WakeLock mise en œuvre, de prendre un coup d'oeil à CommonsWare de WakeLock bibliothèque. Il n'est pas mauvais.
Vous devez vous connecter pour publier un commentaire.
Ok je crois que j'ai trouvé le problème.
Le WakeLock de référence est comptée. Cela signifie que si un deuxième
acquire()
il arrive, il va juste augmenter le nombre de références. Chaque appel à
acquire()
doit être protégé par un appel à
isHeld()
comme dans:J'avais supposé que
acquire()
sur un verrou, j'ai tenu a rien de siplusieurs
acquire()
appels ont causé le problème. Depuis la référencele comte n'est pas zéro, le GC renvoie une erreur.
Je sais que cette question est ancienne, mais gardez à l'esprit que WakeLocks sont "référence compter" par défaut. Vous pouvez désactiver le comptage de référence à l'aide de
setReferenceCounted(boolean)
, voir http://developer.android.com/reference/android/os/PowerManager.WakeLock.html#setReferenceCounted(boolean)Non, il est seulement une déclaration à la portée mondiale et tous les
les appels à l'acquérir() et release() se produisent dans ce champ d'application. J'
println quand ils se produisent et l'acquérir() se produit une fois et la
la libération se produit une fois.