Novità sul prodotto

Ottimizza la batteria della tua app utilizzando la metrica wakelock di Android vitals

Lettura di 7 minuti
Alice Yuan
Developer Relations Engineer

La durata della batteria è un aspetto fondamentale dell'esperienza utente e i wake lock svolgono un ruolo importante. Li utilizzi in modo eccessivo? In questo post del blog esploreremo cosa sono i wake lock, quali sono alcune best practice per utilizzarli e come puoi comprendere meglio il comportamento della tua app con la metrica di Play Console.

Utilizzo eccessivo di wakelock parziali in Android vitals

Play Console ora monitora il consumo eccessivo della batteria, con particolare attenzione all'utilizzo eccessivo di wakelock parziali, come indicatore chiave di rendimento.

Questa funzionalità aumenta l'importanza dell'efficienza della batteria insieme agli indicatori di stabilità delle metriche principali esistenti: arresti anomali ed errori ANR percepiti dall'utente eccessivi. Abbiamo definito una soglia relativa alle prestazioni scadenti per i wakelock eccessivi. A partire dal 1° marzo 2026, se il tuo titolo non soddisfa questa soglia di qualità, potremmo escluderlo dalle piattaforme di scoperta in primo piano, come i consigli. In alcuni casi, potremmo visualizzare un avviso nella scheda dello Store per indicare agli utenti che la tua app potrebbe causare un consumo eccessivo della batteria.

warning.png

L'avviso di wakelock eccessivo nella panoramica di Android vitals.

Per i dispositivi mobili, la metrica Android vitals si applica ai wakelock non esenti acquisiti mentre lo schermo è spento e l'app è in background o esegue un servizio in primo piano. Android vitals considera eccessivo l'utilizzo di wakelock parziali se:

  • I wake lock vengono mantenuti per almeno due ore in un periodo di 24 ore.
  • Interessa più del 5% delle sessioni della tua app, in media su 28 giorni.

I wakelock creati dalle API avviate dall'utente per audio, posizione e JobScheduler sono esenti dal calcolo dei wakelock.

Informazioni sui wakelock

Un wakelock è un meccanismo che consente a un'app di mantenere in esecuzione la CPU di un dispositivo anche quando l'utente non interagisce attivamente con il dispositivo. 

Un wakelock parziale mantiene la CPU in esecuzione anche se lo schermo è spento, impedendo alla CPU di entrare in uno stato di "sospensione" a basso consumo energetico. Un wakelock completo mantiene attivi sia lo schermo che la CPU.

Esistono due metodi per acquisire i wakelock parziali:

  • L'app acquisisce e rilascia manualmente il wakelock utilizzando le API PowerManager per un caso d'uso specifico. Spesso, questa operazione viene eseguita in combinazione con un servizio in primo piano, un'API del ciclo di vita della piattaforma pensata per operazioni percepibili dall'utente.
  • In alternativa, il wakelock viene acquisito da un'altra API e attribuito all'app a causa dell'utilizzo dell'API. Scopri di più nella sezione delle best practice.

Sebbene i wakelock siano necessari per attività come il completamento di un download avviato dall'utente di un file di grandi dimensioni, il loro utilizzo eccessivo o improprio può causare un consumo eccessivo della batteria. Abbiamo riscontrato casi in cui le app mantengono i wakelock per ore o non li rilasciano correttamente, il che ha portato a reclami degli utenti per un consumo eccessivo della batteria anche quando non interagiscono con l'app.

Best practice per l'utilizzo dei wakelock

Prima di esaminare come eseguire il debug dell'utilizzo eccessivo di wakelock, assicurati di seguire le best practice per i wakelock. 

Considera queste quattro domande fondamentali.


1. Hai preso in considerazione opzioni alternative di wakelock?

Prima di prendere in considerazione l'acquisizione di un wakelock parziale manuale, segui questo diagramma di flusso decisionale:

wakelock.png

Diagramma di flusso per decidere quando acquisire manualmente un wakelock

  1. Lo schermo deve rimanere acceso?
  2. L'applicazione esegue un servizio in primo piano?
    • No: non è necessario acquisire manualmente un wakelock.
  3. È dannoso per l'esperienza utente se il dispositivo va in sospensione?
    • No: ad esempio, l'aggiornamento di una notifica dopo il riattivazione del dispositivo non richiede un wakelock.
    • Sì: se è fondamentale impedire la sospensione del dispositivo, ad esempio per la comunicazione continua con un dispositivo esterno, procedi.
  4. Esiste già un'API che mantiene attivo il dispositivo per tuo conto?
    • Puoi utilizzare la documentazione Identificare i wakelock creati da altre API per identificare gli scenari in cui i wakelock vengono creati da altre API, ad esempio LocationManager.
    • Se non esistono API, vai alla domanda finale.
  5. Se hai risposto a tutte queste domande e hai stabilito che non esiste un'alternativa, devi procedere con l'acquisizione manuale di un wakelock.

2. Stai assegnando il nome al wakelock correttamente?

Quando acquisisci manualmente i wake lock, la denominazione corretta è importante per il debug:

  • Non includere informazioni che consentono l'identificazione personale (PII) nel nome, ad esempio indirizzi email. Se vengono rilevate PII, il wakelock viene registrato come _UNKNOWN, il che ostacola il debug.
  • Non assegnare un nome al wakelock in modo programmatico utilizzando nomi di classi o metodi, in quanto questi possono essere offuscati da strumenti come Proguard. Utilizza invece una stringa hardcoded.
  • Non aggiungere contatori o identificatori univoci ai tag wakelock. Lo stesso tag deve essere utilizzato ogni volta che viene eseguito il wakelock per consentire al sistema di aggregare l'utilizzo per nome, rendendo più facile il rilevamento di comportamenti anomali.

3. Il wakelock acquisito viene sempre rilasciato?

Se acquisisci un wakelock manualmente, assicurati che il rilascio del wakelock venga sempre eseguito. Se non rilasci un wakelock, potresti causare un consumo eccessivo della batteria. 

Ad esempio, se viene generata un'eccezione non rilevata durante processingWork(), la chiamata release() potrebbe non verificarsi mai. In alternativa, puoi utilizzare un blocco try-finally per garantire il rilascio del wakelock, anche se si verifica un'eccezione.

Inoltre, puoi aggiungere un timeout al wakelock per assicurarti che venga rilasciato dopo un periodo di tempo specifico, impedendone la detenzione a tempo indeterminato.

  fun processingWork() {
    wakeLock.apply {
        try {
            acquire(60 * 10 * 1000) // timeout after 10 minutes
            doTheWork()
        } finally {
            release()
        }
    }
}

4. Puoi ridurre la frequenza di riattivazione?

Per le richieste di dati periodiche, ridurre la frequenza con cui l'app riattiva il dispositivo è fondamentale per l'ottimizzazione della batteria. Alcuni esempi di riduzione della frequenza di riattivazione includono:

  • WorkManager:aumenta l'intervallo periodico in PeriodicWorkRequest.
  • SensorManager: sfrutta il batch specificando maxReportLatencyMs durante la registrazione del listener.
  • Fused Location Provider:
    • Riduci la frequenza di recupero della posizione utilizzando getLastLocation per la posizione più recente memorizzata nella cache.
    • Utilizza setPriority(PRIORITY_PASSIVE) per un metodo di aggiornamento che consuma meno batteria.
    • Inoltre, puoi sfruttare il meccanismo di raggruppamento delle posizioni impostando un intervallo di aggiornamento minimo con setMinUpdateIntervalMillis.

Per ulteriori dettagli, consulta la documentazione sulle best practice per i wakelock.

Debug dell'utilizzo eccessivo dei wakelock

Anche con le migliori intenzioni, può verificarsi un utilizzo eccessivo del wakelock. Se la tua app viene segnalata in Play Console, ecco come eseguire il debug:

Identificazione iniziale con Play Console

La dashboard dei wakelock parziali eccessivi di Android vitals fornisce suddivisioni dei nomi dei wakelock non esenti associati alla tua app, mostrando le sessioni e le durate interessate. Ti ricordiamo di utilizzare la documentazione per identificare se il nome del wakelock è detenuto dall'app o da un'altra API.

breakdowns2.png

La dashboard Wakelock parziali eccessivi di Android vitals è stata spostata verso il basso fino alla sezione delle suddivisioni per visualizzare i tag wakelock eccessivi.

Debug dei wake lock eccessivi mantenuti da worker/job

Puoi identificare i wakelock mantenuti dal worker con questo nome:

*job*/<package_name>/androidx.work.impl.background.systemjob.SystemJobService

L'elenco completo delle varianti dei nomi dei wakelock detenuti dai worker è disponibile nella documentazione. Per eseguire il debug di questi wakelock, puoi utilizzare Background Task Inspector per eseguire il debug in locale o sfruttare getStopReason per eseguire il debug dei problemi sul campo. 

Android Studio Background Task Inspector

taskinspector.png


Acquisizione schermo di Background Task Inspector, in cui è stato possibile identificare un worker "WeatherSyncWorker" che ha eseguito di frequente nuovi tentativi senza esito.

Per il debug locale dei problemi di WorkManager, utilizza questo strumento su un emulatore o un dispositivo connesso (livello API 26+). Mostra un elenco di worker e dei relativi stati (terminato, in esecuzione, in coda), consentendoti di esaminare i dettagli e comprendere le catene di worker. 

Ad esempio, può rivelare se un worker non funziona correttamente o riprova spesso a causa di limitazioni del sistema. 

Per ulteriori dettagli, consulta la documentazione di Background Task Inspector.

WorkManager getStopReason

Per il debug sul campo dei worker con blocchi di riattivazione eccessivi, utilizza WorkInfo.getStopReason() su WorkManager 2.9.0 o versioni successive oppure per JobScheduler, JobParameters.getStopReason() disponibile su SDK 31 e versioni successive. 

Questa API consente di registrare il motivo per cui un worker si è arrestato (ad es. STOP_REASON_TIMEOUTSTOP_REASON_QUOTA), individuando problemi come timeout frequenti dovuti all'esaurimento della durata del runtime.

  backgroundScope.launch {
    WorkManager.getInstance(context)
        .getWorkInfoByIdFlow(workRequest.id)
        .collect { workInfo ->
            logStopReason(workRequest.id, workInfo?.stopReason)
        }
}

Per maggiori dettagli, consulta Ottimizzare l'utilizzo della batteria per le API di pianificazione delle attività.

Debug di altri tipi di wakelock eccessivi

Per scenari più complessi che coinvolgono wakelock mantenuti manualmente o API che mantengono il wakelock, ti consigliamo di utilizzare la raccolta delle tracce di sistema per il debug.

Raccolta delle tracce di sistema

Una traccia di sistema è un potente strumento di debug che acquisisce un record dettagliato dell'attività di sistema in un periodo di tempo, fornendo informazioni sullo stato della CPU, sull'attività dei thread, sull'attività di rete e su metriche relative alla batteria come la durata del job e l'utilizzo del wakelock.

Puoi acquisire una traccia di sistema utilizzando diversi metodi: 

powermgmt.png

Attiva la categoria Atrace "power:PowerManagement" nell'interfaccia utente di Perfetto nella scheda App e servizi Android. 

Indipendentemente dal metodo scelto, è fondamentale assicurarsi di raccogliere la categoria Atrace "power:PowerManagement" per consentire la visualizzazione delle tracce dello stato del dispositivo. 

Perfetto UI inspection and SQL analysis

Le tracce di sistema possono essere aperte e ispezionate nell'interfaccia utente di Perfetto. Quando apri la traccia, visualizzi una visualizzazione di vari processi su una cronologia. Le tracce su cui ci concentreremo in questa guida sono quelle in "Stato del dispositivo".

perfetto.png


Blocca le tracce in "Stato dispositivo", ad esempio "App principale", "Stato schermo", "wakelock lunghi" e "Job", per identificare visivamente le sezioni di wakelock di lunga durata.

Ogni blocco elenca il nome dell'evento, la data di inizio e la data di fine. In Perfetto, questo elemento è chiamato slice.

Per un'analisi scalabile di più tracce, puoi utilizzare l'analisi SQL di Perfetto. Una query SQL può trovare tutti i wake lock ordinati per durata, contribuendo a identificare i principali responsabili dell'utilizzo eccessivo.

Ecco un esempio di query che somma tutti i tag wakelock che si sono verificati nella traccia di sistema, ordinati in base alla durata totale:

  SELECT slice.name as name, track.name as track_name,SUM(dur / 100000) as total_dur_ms
FROM slice
JOIN track ON slice.track_id = track.id
WHERE track.name = 'WakeLocks'GROUP BY slice.name, track.name
ORDER BY total_dur_ms DESC

Utilizzare ProfilingManager per la raccolta delle tracce sul campo

Per i problemi difficili da riprodurre, ProfilingManager (aggiunto nell'SDK 35) è un'API programmatica che consente agli sviluppatori di raccogliere tracce di sistema sul campo con trigger di inizio e fine. Offre un maggiore controllo sui punti di attivazione iniziale e finale per la raccolta dei profili e applica la limitazione della frequenza a livello di sistema per evitare un impatto sulle prestazioni del dispositivo. 

Consulta la documentazione di ProfilingManager per ulteriori passaggi su come implementare la raccolta delle tracce di sistema sul campo, tra cui come acquisire una traccia, analizzare i dati di profilazione e utilizzare i comandi di debug locali.

Le tracce di sistema raccolte utilizzando ProfilingManager avranno un aspetto simile a quelle raccolte manualmente, ma i processi di sistema e altri processi dell'app vengono oscurati dalla traccia.

Conclusione

La metrica wakelock parziali eccessivi in Android vitals è solo una piccola parte del nostro impegno costante a supportare gli sviluppatori nella riduzione del consumo eccessivo della batteria e nel miglioramento della qualità delle app. 

Comprendendo e implementando correttamente i wake lock, puoi ottimizzare in modo significativo le prestazioni della batteria della tua app. L'utilizzo di API alternative, il rispetto delle best practice per i wakelock e l'utilizzo di potenti strumenti di debug come Background Task Inspector, le tracce di sistema e ProfilingManager sono fondamentali per garantire il successo della tua app su Google Play.

Scritto da:

Continua a leggere