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.
Nommez 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 dans votre 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 le tag de wakelock, il enregistre
_UNKNOWNau lieu du tag que vous avez spécifié. - 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 le même tag chaque fois qu'il s'exécute. Cette pratique permet au système d'agréger l'utilisation de 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 être informé de ce qui se passe. Pour cette raison, 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 non plus utiliser de wakelock. Consultez la documentation Choisir la bonne API pour maintenir l'appareil activé pour découvrir d'autres façons d'effectuer des tâches lorsque votre application n'est pas au premier plan.
Simplifiez 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érifiez 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 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 elle n'atteint jamais l'appel release(). Le résultat est que 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();
}
}