Seguire le best practice per il blocco risveglio

L'utilizzo di un wake lock 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 le insidie comuni dei wake lock.

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 blocco di riattivazione. Ecco alcuni suggerimenti aggiuntivi:

  • Non includere informazioni che consentono l'identificazione personale (PII) nel nome, ad esempio un indirizzo email. Se il dispositivo rileva PII nel tag wake lock, registra _UNKNOWN anziché 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 codificata.
  • Non aggiungere un contatore o identificatori unici ai tag wake lock. Il codice che crea un wake lock deve utilizzare lo stesso tag ogni volta che viene eseguito. Questa pratica consente al sistema di aggregare l'utilizzo del wake lock di ogni metodo.

Assicurati che la tua app sia visibile in primo piano

Mentre un wake lock è attivo, il dispositivo consuma energia. L'utente del dispositivo deve essere consapevole di ciò che sta accadendo. Per questo motivo, se utilizzi un wake lock, devi mostrare una notifica all'utente. In pratica, ciò significa che devi ottenere 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 wake lock sia il più semplice possibile. Quando la logica di blocco della riattivazione è legata a macchine a stati complessi, timeout, pool di esecutori o eventi di callback, qualsiasi bug sottile in questa logica può causare il mantenimento del blocco della riattivazione più a lungo del previsto. Questi bug sono difficili da diagnosticare e da eseguire il debug.

Verifica che il wake lock 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 wake lock viene acquisito ma non rilasciato, il che è molto grave.

Nel codice corretto, doSomethingAndRelease() si assicura di rilasciare il wake lock 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();
    }
}