L'utilizzo di un wakelock può compromettere le prestazioni del dispositivo. Se devi utilizzare un wakelock, è importante farlo correttamente. Questo documento illustra alcune best practice che possono aiutarti a evitare i problemi comuni relativi ai wakelock.
Assegna un nome corretto al wakelock
Ti consigliamo di includere il nome del pacchetto, della classe o del metodo nel tag wakelock. In questo modo, se si verifica un errore, è più facile trovare la posizione nel codice sorgente in cui è stato creato il wakelock. Ecco alcuni suggerimenti aggiuntivi:
- Non includere nel nome informazioni che consentono l'identificazione personale (PII), come un indirizzo email. Se il dispositivo rileva PII nel tag del wakelock, registra
_UNKNOWNanziché il tag specificato. - Non recuperare il nome della classe o del metodo in modo programmatico, ad esempio chiamando
getName(). Se provi a ottenere il nome in modo programmatico, potrebbe essere offuscato da strumenti come Proguard. Utilizza invece una stringa hardcoded. - Non aggiungere un contatore o identificatori univoci ai tag wakelock. Il codice che crea un wakelock deve utilizzare lo stesso tag ogni volta che viene eseguito. In questo modo, il sistema può aggregare l'utilizzo dei wakelock di ogni metodo.
Assicurati che l'app sia visibile in primo piano
Quando un wakelock è attivo, il dispositivo consuma energia. L'utente del dispositivo deve essere consapevole di ciò che sta accadendo. Per questo motivo, se utilizzi un wakelock, devi mostrare una notifica all'utente. In pratica, ciò significa che devi acquisire e mantenere il wakelock in un servizio in primo piano. I servizi in primo piano devono mostrare una notifica.
Se un servizio in primo piano non è la scelta giusta per la tua app, probabilmente non dovresti utilizzare nemmeno un wakelock. Consulta la documentazione Scegli l'API giusta per mantenere attivo il dispositivo per altri modi per eseguire operazioni mentre l'app non è in primo piano.
Mantieni la logica semplice
Assicurati che la logica per l'acquisizione e il rilascio dei wakelock sia il più semplice possibile. Quando la logica del wakelock è legata a macchine a stati complessi, timeout, pool di esecutori o eventi di callback, qualsiasi bug impercettibile in quella logica può far sì che il wakelock venga mantenuto più a lungo del previsto. Questi bug sono difficili da diagnosticare e correggere.
Verifica che il wakelock venga sempre rilasciato
Se utilizzi un wakelock, devi assicurarti che ogni wakelock acquisito venga rilasciato correttamente. Non è sempre facile come sembra. Ad esempio, il seguente codice presenta un 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
}
Il problema è che il metodo doTheWork() può generare l'eccezione MyException. In questo caso, il metodo doSomethingAndRelease() propaga l'eccezione verso l'esterno e non raggiunge mai la chiamata release(). Il risultato è che il wakelock viene acquisito, ma non rilasciato, il che è molto negativo.
Nel codice corretto, doSomethingAndRelease() si assicura di rilasciare il wakelock anche se viene generata un'eccezione:
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();
}
}