Se non presti attenzione, lavorare con le immagini può causare rapidamente problemi di prestazioni. Anche una piccola grafica in un formato compresso come JPG o PNG può trasformarsi in una bitmap di grandi dimensioni quando viene decodificata per la visualizzazione.Se non utilizzi le grafiche in modo efficiente, potresti riscontrare problemi di memoria che possono compromettere le prestazioni della tua app e di altre app sul dispositivo. Segui queste best practice per assicurarti che la tua app funzioni al meglio.
Utilizzare le librerie di caricamento delle immagini
Puoi migliorare l'efficienza della tua app utilizzando librerie di caricamento delle immagini come Coil (per i progetti Kotlin-first) o Glide (per i progetti Java). Queste librerie riducono la memoria utilizzata dalla tua app eseguendo operazioni come la memorizzazione nella cache delle immagini, il ridimensionamento delle grafiche quando necessario e il riciclo degli oggetti grafici.
Ridimensionare le immagini quando appropriato
Assicurati di utilizzare le dimensioni dell'immagine appropriate per le tue esigenze. Ad esempio, non dovresti mai caricare un'immagine di grandi dimensioni in una miniatura piccola. Utilizza invece un metodo
come inSampleSize per caricare una versione ricampionata dell'immagine.
Per impostazione predefinita, le librerie di caricamento delle immagini come Coil e Glide gestiscono automaticamente questo ricampionamento. Puoi configurare le strategie di sottocampionamento utilizzando
ImageLoader (per Coil) o DownsampleStrategy (per Glide).
Fornire risorse alternative per diverse dimensioni dello schermo
Se distribuisci immagini con la tua app, valuta la possibilità di fornire asset di dimensioni diverse per le diverse risoluzioni dei dispositivi. Questo può contribuire a ridurre le dimensioni del download dell'app sui dispositivi e a migliorare le prestazioni, poiché caricherà un'immagine a risoluzione inferiore su un dispositivo a risoluzione inferiore. Per ulteriori informazioni sulla fornitura di bitmap alternative per diverse dimensioni dei dispositivi, consulta la documentazione relativa alle bitmap alternative bitmap.
Non applicare direttamente il padding
A volte potrebbe essere necessario aggiungere un padding a un'immagine. Ad esempio, potresti voler circondare l'immagine con un bordo trasparente per il letterboxing.
In questi casi, non aggiungere il padding direttamente all'immagine, modificandone
le dimensioni. Lascia invece le dimensioni dell'immagine così come sono,
e regola la posizione dell'immagine sullo schermo utilizzando InsetDrawable.
In alternativa, puoi aggiungere il padding al Composable o alla View che contiene l'immagine.
Scegliere il formato pixel corretto
Bilancia memoria e qualità scegliendo il formato pixel corretto. Utilizza RGB_565 quando non hai bisogno di trasparenza. Questo formato utilizza la metà della memoria del formato predefinito ARGB_8888.
In Glide puoi configurare questa opzione utilizzando DecodeFormat. In Coil, puoi
utilizzare la bitmapConfig proprietà.
Utilizzare i vettori, se possibile
Per le immagini composte da forme geometriche, una grafica vettoriale è molto più piccola di una bitmap e si adatta perfettamente a qualsiasi densità di visualizzazione. Quando è appropriato, utilizza elementi
come ShapeDrawable per rappresentare le grafiche.
Rilasciare e riutilizzare le bitmap quando possibile
I file grafici di grandi dimensioni possono occupare molta memoria. Per ridurre il loro impatto, dovresti rilasciare o riutilizzare gli oggetti grafici ogni volta che puoi.
Se utilizzi una libreria di caricamento delle immagini, assicurati di rilasciare le bitmap nel pool gestito della libreria quando non ne hai più bisogno. La libreria può riutilizzare gli oggetti quando necessario e mantiene un buffer di memoria disponibile per le esigenze future.
Se gestisci le grafiche manualmente, devi rilasciare
le bitmap quando hai finito di utilizzarle chiamando Bitmap.recycle
e scartando immediatamente il riferimento Bitmap, anziché
affidarti alla garbage collection.
Altri suggerimenti e trucchi
Questa sezione elenca alcuni altri modi per migliorare le prestazioni della tua app durante la gestione delle grafiche.
Non includere immagini di grandi dimensioni nel file AAB/APK
Una delle cause principali delle dimensioni di download dell'app elevate sono le grafiche incluse nel file AAB o APK. Utilizza lo strumento di analisi APK per assicurarti di non includere file di immagine più grandi del necessario. Riduci le dimensioni o valuta la possibilità di inserire le immagini su un server e di scaricarle solo quando necessario.
Trovare bitmap ridondanti
Se hai più copie della stessa immagine, la memoria viene sprecata. Puoi utilizzare il profiler di Android Studio per identificare le grafiche ridondanti. Utilizza l'analizzatore di dump dell'heap per acquisire un dump dell'heap e filtra i risultati scegliendo l'impostazione Bitmap duplicate.
Quando utilizzi ImageBitmap, chiama prepareToDraw prima di disegnare
Quando utilizzi ImageBitmap, per avviare il processo di caricamento della texture sulla
GPU, chiama ImageBitmap#prepareToDraw() prima di disegnarla effettivamente. In questo modo la GPU prepara la texture e migliora le prestazioni della visualizzazione sullo schermo. La maggior parte delle librerie di caricamento delle immagini esegue già questa ottimizzazione, ma se lavori direttamente con la classe ImageBitmap, è un aspetto da tenere presente.
Preferisci passare un Int DrawableRes o un URL come parametri al tuo composable anziché Painter
A causa della complessità della gestione delle immagini (ad esempio, scrivere una funzione equals
per Bitmaps sarebbe costoso dal punto di vista computazionale), l'API Painter non è
contrassegnata esplicitamente come stabile con l'annotazione @Stable. Le classi instabili possono causare ricomposizioni non necessarie perché il compilatore non può dedurre facilmente se i dati sono cambiati.
Pertanto, ti consigliamo di passare un URL o un ID risorsa disegnabile come parametri al tuo composable, anziché passare un Painter come parametro.
// Prefer this:
@Composable
fun MyImage(url: String) {
}
// Over this:
@Composable
fun MyImage(painter: Painter) {
}
Consigliati per te
- Nota: il testo del link viene visualizzato quando JavaScript è disattivato
- ImageBitmap versus ImageVector {:#bitmap-vs-vector}
- Salvare lo stato dell'UI in Compose
- Fasi di Jetpack Compose