O uso de um wake lock pode prejudicar o desempenho do dispositivo. Se você precisar usar um bloqueio de ativação, é importante fazer isso corretamente. Este documento aborda algumas práticas recomendadas que podem ajudar você a evitar armadilhas comuns de bloqueio de despertar.
Nomeie o wake lock corretamente
Recomendamos que você inclua o nome do pacote, da classe ou do método na tag wakelock. Assim, se ocorrer um erro, será mais fácil encontrar o local no código-fonte em que o bloqueio de despertar foi criado. Veja mais algumas dicas:
- Não inclua informações de identificação pessoal (PII, na sigla em inglês) no nome,
como um endereço de e-mail. Se o dispositivo detectar informações de identificação pessoal na tag
do wake lock, ele vai registrar
_UNKNOWN
em vez da tag especificada. - Não busque o nome da classe ou do método de forma programática, por exemplo, chamando
getName()
. Se você tentar buscar o nome de forma programática, ele poderá ser ofuscado por ferramentas como o Proguard. Em vez disso, use uma string codificada. - Não adicione um contador ou identificadores exclusivos às tags de wake lock. O código que cria um bloqueio de despertar precisa usar a mesma tag sempre que for executado. Essa prática permite que o sistema agregue o uso de bloqueio de despertar de cada método.
Verifique se o app está visível em primeiro plano
Enquanto um wake lock está ativo, o dispositivo está usando energia. O usuário do dispositivo precisa saber que isso está acontecendo. Por isso, se você estiver usando um wake lock, mostre uma notificação ao usuário. Na prática, isso significa que você precisa receber e manter o wakelock em um serviço em primeiro plano. Os serviços em primeiro plano precisam mostrar uma notificação.
Se um serviço em primeiro plano não for a escolha certa para seu app, provavelmente você também não deve usar um bloqueio de despertar. Consulte a documentação Escolher a API certa para manter o dispositivo ativo e saiba outras maneiras de trabalhar enquanto o app não está em primeiro plano.
Mantenha a lógica simples
Confira se a lógica para adquirir e liberar wake locks é o mais simples possível. Quando sua lógica de wake lock está vinculada a máquinas de estado, tempos limite, pool de executores ou eventos de callback complexos, qualquer bug sutil nessa lógica pode fazer com que o wake lock seja mantido por mais tempo do que o esperado. Esses bugs são difíceis de diagnosticar e depurar.
Verifique se o wake lock é sempre liberado
Se você usa um wake lock, verifique se todos os wake locks adquiridos são liberados corretamente. Nem sempre é tão fácil quanto parece. Por exemplo, o código a seguir tem um problema:
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
}
O problema aqui é que o método doTheWork()
pode gerar a exceção MyException
. Se isso acontecer, o método doSomethingAndRelease()
vai propagar
a exceção para fora, e ela nunca vai chegar à chamada release()
. O resultado
é que o bloqueio de despertar é adquirido, mas não liberado, o que é muito ruim.
No código corrigido, doSomethingAndRelease()
garante a liberação do
bloqueio de despertar mesmo que uma exceção seja gerada:
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();
}
}