L'utilisation d'un wakelock peut nuire aux performances de l'appareil. Si vous devez utiliser un wakelock, il est important de le faire correctement. Ce document présente quelques bonnes pratiques qui peuvent vous aider à éviter les pièges courants liés aux wakelocks.
Nommer correctement le wakelock
Nous vous recommandons d'inclure le nom du package, de la classe ou de la méthode dans la balise de wakelock. Ainsi, en cas d'erreur, il est plus facile de trouver l'emplacement du code source où le wakelock a été créé. Voici quelques conseils supplémentaires :
- N'indiquez aucune information permettant d'identifier personnellement l'utilisateur dans le nom, comme une adresse e-mail. Si l'appareil détecte des informations permettant d'identifier personnellement l'utilisateur dans la balise de wakelock, il enregistre
_UNKNOWNau lieu de la balise que vous avez spécifiée. - N'obtenez pas le nom de la classe ou de la méthode par programmation, par exemple en appelant
getName(). Si vous essayez d'obtenir le nom par programmation, il peut être obscurci par des outils tels que ProGuard. Utilisez plutôt une chaîne codée en dur. - N'ajoutez pas de compteur ni d'identifiants uniques pour réactiver les balises de wakelock. Le code qui crée un wakelock doit utiliser la même balise à chaque exécution. Cette pratique permet au système d'agréger l'utilisation du wakelock de chaque méthode.
Assurez-vous que votre application est visible au premier plan
Lorsqu'un wakelock est actif, l'appareil consomme de l'énergie. L'utilisateur de l'appareil doit en être informé. Par conséquent, si vous utilisez un wakelock, vous devez afficher une notification à l'utilisateur. En pratique, cela signifie que vous devez obtenir et conserver le wakelock dans un service de premier plan. Les services de premier plan doivent afficher une notification.
Si un service de premier plan n'est pas le bon choix pour votre application, vous ne devriez probablement pas utiliser de wakelock non plus. Consultez la documentation Choisir la bonne API pour maintenir l'appareil actif pour découvrir d'autres façons de travailler lorsque votre application n'est pas au premier plan.
Simplifier la logique
Assurez-vous que la logique d'acquisition et de libération des wakelocks est aussi simple que possible. Lorsque votre logique de wakelock est liée à des machines d'état, à des délais d'exécution, à des pools d'exécuteurs ou à des événements de rappel complexes, tout bug subtil dans cette logique peut entraîner le blocage du wakelock plus longtemps que prévu. Ces bugs sont difficiles à diagnostiquer et à déboguer.
Vérifier que le wakelock est toujours libéré
Si vous utilisez un wakelock, vous devez vous assurer que chaque wakelock que vous acquérez est correctement libéré. Ce n'est pas toujours aussi simple qu'il n'y paraît. Par exemple, le code suivant présente un problème :
Kotlin
@Throws(MyException::class)
fun doSomethingAndRelease() {
wakeLock.apply {
acquire()
doTheWork() // can potentially throw MyException
release() // does not run if an exception is thrown
}
}
Java
void doSomethingAndRelease() throws MyException {
wakeLock.acquire();
doTheWork(); // can potentially throw MyException
wakeLock.release(); // does not run if an exception is thrown
}
Le problème ici est que la méthode doTheWork() peut générer l'exception MyException. Si c'est le cas, la méthode doSomethingAndRelease() propage l'exception vers l'extérieur et n'atteint jamais l'appel release(). Par conséquent, le wakelock est acquis, mais pas libéré, ce qui est très mauvais.
Dans le code corrigé, doSomethingAndRelease() s'assure de libérer le wakelock même si une exception est générée :
Kotlin
@Throws(MyException::class)
fun doSomethingAndRelease() {
wakeLock.apply {
try {
acquire()
doTheWork()
} finally {
release()
}
}
}
Java
void doSomethingAndRelease() throws MyException {
try {
wakeLock.acquire();
doTheWork();
} finally {
wakeLock.release();
}
}