Seguir as práticas recomendadas de bloqueio de ativação

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();
    }
}