Android esegue il rendering dell'interfaccia utente generando un frame dalla tua app e visualizzandolo sullo schermo. Se la tua app presenta un rendering dell'interfaccia utente lento, il sistema deve ignorare i frame. In questo caso, l'utente percepisce sullo schermo uno sfarfallio ricorrente, chiamato jank.
Quando si verifica jank, di solito è a causa di una decelerazione o di un blocco della chiamata asincrona nel thread dell'interfaccia utente (nella maggior parte delle app è il thread principale). Puoi usare le tracce del sistema per identificare la posizione del problema.
Rilevare jank su Android 12 e versioni successive
Per i dispositivi che utilizzano Android 12 (livello API 31) o versioni successive, una traccia acquisita viene mostrata nel canale Frame Janky nel riquadro Display del Profiler CPU.
Per rilevare jank,
In Android Studio, seleziona Visualizza > Finestre degli strumenti > Profiler oppure fai clic su Profilo nella barra degli strumenti.
Se richiesto dalla finestra di dialogo Seleziona destinazione del deployment, scegli il dispositivo su cui eseguire il deployment dell'app per la profilazione. Se hai collegato un dispositivo tramite USB, ma non lo trovi nell'elenco, assicurati di aver attivato il debug USB.
Fai clic in un punto qualsiasi della sequenza temporale CPU per aprire il Profiler CPU.
Seleziona System Trace dal menu Configurazioni nel Profiler CPU e fai clic su Record. Al termine dell'interazione con l'app, fai clic su Interrompi.
Dovresti vedere la traccia Frame Janky sotto Display. Per impostazione predefinita, Profiler mostra solo frame scadenti come candidati per l'indagine. All'interno di ogni frame incompleto, la parte rossa evidenzia la durata del frame oltre la scadenza di rendering.
Una volta trovata una cornice scadente, fai clic su di essa. Se vuoi, puoi premere M per regolare lo zoom e mettere a fuoco il fotogramma selezionato. Gli eventi pertinenti vengono evidenziati in questi thread: il thread principale, RenderThread e il completamento GPU.
Se vuoi, puoi visualizzare tutti i frame o una suddivisione del tempo di rendering attivando/disattivando le caselle di controllo rispettivamente Tutti i frame e Ciclo di vita.
Rilevare jank su Android 11
Per i dispositivi che utilizzano Android 11 (livello API 30), una traccia acquisita viene mostrata nella sezione Ciclo di vita del frame nel Profiler CPU.
La sezione Ciclo di vita dei frame contiene il nome del livello e quattro tracce. Ogni traccia rappresenta una fase della pipeline di rendering del frame. Gli elementi Ciclo di vita dei frame sono i seguenti:
- Ciclo di vita del frame (nome livello): il titolo della sezione contiene il nome del livello tra parentesi. Un livello è una singola unità di composizione.
- Applicazione: questa traccia mostra il tempo trascorso tra il momento in cui il buffer è stato rimosso dalla coda
dall'app e il momento in cui è stato accodato di nuovo. In genere corrisponde agli eventi di traccia in
RenderThread
. - Attendi GPU: questo canale mostra per quanto tempo il buffer è stato di proprietà della GPU. Questo è il tempo che intercorre tra l'invio del buffer alla GPU e il termine del lavoro sul buffer da parte della GPU. Questo non significa che la GPU stava lavorando solo su questo buffer durante questo periodo. Per informazioni dettagliate su ciò su cui funziona la GPU in un determinato periodo di tempo, puoi utilizzare lo strumento Android GPU Inspector.
- Composizione: questa traccia mostra il tempo a partire dal momento in cui SurfaceFlinger si aggancia al buffer e lo invia per la composizione a quando il buffer viene inviato al display.
- Frame on display: questa traccia mostra la durata del frame sullo schermo.
La sezione Ciclo di vita dei frame illustra il modo in cui un buffer frame si sposta tra le diverse fasi della pipeline di rendering. I frame sono codificati per colore in base al numero di frame, in modo che sia più facile rintracciare un determinato frame.
Android Studio mostra inoltre tutti i frame nella traccia in un formato tabella nella scheda Tutti i frame.
Le colonne N. frame, Applicazione, Attendi per GPU e Composizione rappresentano gli stessi dati delle tracce nella sezione Ciclo di vita del frame di cui sopra. La colonna Durata frame rappresenta il tempo dall'inizio dell'applicazione all'inizio della funzionalità Frame on Display. Questo è essenzialmente il tempo necessario per eseguire il rendering di un frame end-to-end.
Puoi ordinare la tabella dei frame in base a qualsiasi colonna per trovare rapidamente il frame più breve o più lungo. La tabella supporta anche i controlli di impaginazione, che consentono di esplorare centinaia di frame.
Per rilevare ed esaminare jank su Android 11, segui questi passaggi:
Ordina la tabella Tutti i frame in base alla colonna Applicazione in ordine decrescente, in modo che i frame che richiedono più tempo appaiano per primi.
Trova i frame più lunghi e seleziona la riga della tabella. Aumenta lo zoom sul frame selezionato nella visualizzazione Sequenza temporale a sinistra.
Cerca i thread pertinenti nelle sezioni Ciclo di vita dei frame e Thread.
Rilevare jank su Android 10 e versioni precedenti
Per i dispositivi che utilizzano Android 10 (livello API 29) e versioni precedenti, le informazioni pertinenti della pipeline grafiche del sistema operativo vengono visualizzate in un'unica sezione nella traccia del sistema CPU Profiler denominata Display.
- Frame: questa sezione mostra il thread dell'interfaccia utente e gli eventi di traccia
RenderThread
nella tua app. Gli eventi che superano i 16 ms vengono di colore rosso per evidenziare potenziali frame scadenti perché superano la scadenza per il rendering a 60 frame al secondo (f/s). - SurfaceFlinger: questa sezione mostra quando il SurfaceFlinger elabora il buffer del frame. SurfaceFlinger è un processo di sistema responsabile dell'invio dei buffer da visualizzare.
- VSYNC: questa sezione mostra VSYNC, un indicatore che sincronizza la pipeline di visualizzazione. Il brano mostra il segnale VSYNC-app, che viene mostrato quando la tua app si avvia troppo tardi. In genere, ciò si verifica perché il thread della UI è occupato. Questo causa la visualizzazione di uno sfarfallio visibile sullo schermo durante un'animazione e aggiunge ulteriore latenza di input fino al completamento dell'animazione o dello scorrimento. Questo aspetto è particolarmente importante per visualizzazioni con frequenza di aggiornamento elevata, in quanto possono verificarsi più di 60 volte al secondo o a una frequenza variabile.
- BufferQueue: questa sezione mostra il numero di buffer frame in coda e in attesa di utilizzo da parte di SurfaceFlinger. Per le app distribuite su dispositivi con Android 9 (livello API 28) o versioni successive, questo canale mostra il conteggio del buffer della piattaforma dell'app BufferQueue (
0
,1
o2
). BufferQueue può aiutarti a comprendere lo stato dei buffer delle immagini mentre si spostano tra i componenti grafici Android. Ad esempio, il valore2
indica che l'app è attualmente con triplo buffer, il che comporta una latenza di input aggiuntiva.
La sezione Display fornisce segnali utili per rilevare potenziali jank, ad esempio quando il thread dell'interfaccia utente o RenderThread
richiede più di 16 ms. Per esaminare i dettagli esatti della causa del jank, puoi esaminare la sezione Thread, che mostra i thread pertinenti al rendering dell'interfaccia utente.
Nella figura sopra, la sezione Thread mostra il thread dell'interfaccia utente
(java.com.google.samples.apps.iosched
), RenderThread
e il thread GPU completion
. Questi sono i thread pertinenti al rendering dell'interfaccia utente e possono contribuire al
jank.
Per rilevare jank su Android 10 o versioni precedenti, segui questi passaggi:
Esamina la traccia Frame in Display. I frame rossi sono candidati per l'indagine.
Una volta individuato un fotogramma potenzialmente pericoloso, aumenta lo zoom premendo
W
o facendo scorrere la rotellina del mouse tenendo premuto Ctrl (Comando su macOS). Continua ad aumentare lo zoom finché non inizi a vedere gli eventi di traccia nel thread dell'interfaccia utente e inRenderThread
.Nella figura sopra,
Choreographer#doFrame
mostra quando il thread dell'interfaccia utente chiamaChoreographer
per coordinare l'animazione, visualizzare il layout, il disegno di immagini e i processi correlati.DrawFrames
viene visualizzato quandoRenderThread
formula ed emette comandi di disegno effettivi alla GPU.Se noti un evento traccia particolarmente lungo, puoi aumentare ulteriormente lo zoom e scoprire cosa potrebbe aver contribuito alla lentezza del rendering. La figura sopra mostra
inflate
nel thread dell'interfaccia utente, il che significa che l'app sta aumentando il tempo del layout. Quando aumenti lo zoom su uno degli eventiinflate
, puoi scoprire esattamente quanto tempo impiega ogni componente dell'interfaccia utente, come mostrato di seguito.
Scopri di più
Per scoprire di più su come ridurre il jank, consulta Origini comuni di jank.