O uso de um wake lock pode prejudicar o desempenho do dispositivo. Se você precisar usar um bloqueio de desbloqueio, é importante fazer isso corretamente. Este documento aborda algumas práticas recomendadas que podem ajudar você a evitar armadilhas comuns de bloqueio de ativação.
Nomeie o wake lock corretamente
Recomendamos que você inclua o nome do pacote, da classe ou do método na tag do wakelock. Dessa forma, se ocorrer um erro, será mais fácil encontrar o local no código-fonte em que a trava de ativação foi criada. 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 PII na tag de 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 ativação precisa usar a mesma tag sempre que for executado. Essa prática permite que o sistema agregue o uso do bloqueio de ativação de cada método.
Confira se o app está visível em primeiro plano
Enquanto um bloqueio de ativação está ativo, o dispositivo está usando energia. O usuário do dispositivo precisa estar ciente disso. Por esse motivo, 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 são necessários para mostrar uma notificação.
Se um serviço em primeiro plano não for a escolha certa para seu app, provavelmente você não deve usar um bloqueio de ativação. Consulte a documentação Escolher a API certa para manter o dispositivo ativo para conferir 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 a lógica de wake lock está vinculada a máquinas de estado, tempos limite, pools 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.
Verificar se o wake lock é sempre liberado
Se você usar um wake lock, verifique se todos os wake locks adquiridos foram liberados corretamente. Isso nem sempre é tão fácil quanto parece. Por exemplo, o código abaixo 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 nunca vai chegar à chamada release()
. O resultado
é que o bloqueio de ativação é adquirido, mas não é liberado, o que é muito ruim.
No código corrigido, doSomethingAndRelease()
libera o
bloqueio de ativação, 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();
}
}