Sto usando la glide per il caricamento delle immagini nella mia app per Android, per evitare arresti anomali Sto caricando immagini con contesto applicativo. Quale sarà l'effetto di questo sulle prestazioni dell'applicazione e della memoria?Caricamento immagine scivolata con contesto applicativo
risposta
Quale sarà l'effetto di questo sulle prestazioni dell'applicazione e della memoria?
Glide offre così tante .with()
metodi per un motivo: ne consegue ciclo di vita.
Immaginate uno Fragment
aggiunto dinamicamente ad un'attività. Nel suo metodo onCreateView
avvia un carico Glide di un'immagine da 3MB. Ora, cosa succede se l'utente preme il pulsante Indietro e il frammento viene rimosso o l'intera attività è chiusa?
- Se si utilizza
with(getActivity().getApplicationContext())
nulla accadrà, tutti 3MBs di dati vengono scaricati e poi decodificati, cache, probabilmente anche impostare al ImageView, che viene poi garbage collection, perché l'unico riferimento ad essa era da interni Glide. - Se si utilizza
with((Fragment)this)
Glide si iscrive agli eventi del ciclo di vita di Fragment e non appena il frammento viene arrestato, tutte le richieste in sospeso devono essere sospese; e una volta distrutto, tutte le richieste in sospeso verranno cancellate. Ciò significa che il download dell'immagine si interromperà a metà strada e non verranno più utilizzate risorse da quel frammento morto. - Se si utilizza
with(getActivity())
Glide si iscrive agli eventi del ciclo di vita dell'Attività e la stessa cosa accade come sopra, ma solo quando l'attività viene interrotta o distrutta.
Quindi la best practice è usare il contesto/frammento più vicino possibile per evitare il completamento di richieste inutilizzate! (C'è anche un modo manuale per fermare un carico:. Glide.clear(ImageView|Target)
)
Per applicare questo, in pratica, cercare di utilizzare with(this)
quando possibile, ma quando non lo è, come in un adattatore, o di un metodo di caricamento delle immagini centralizzata, passare un RequestManager glide
come argomento e utilizzare glide.load(...
, ad esempio:
static loadImage(RequestManager glide, String url, ImageView view) {
glide.load(url).into(view);
}
o adattatore:
class MyAdapter extends WhichEveryOneYouUse {
private final RequestManager glide;
MyAdapter(RequestManager glide, ...) {
this.glide = glide;
...
}
void getView/onBindViewHolder(... int position) {
// ... holder magic, and get current item for position
glide.load... or even loadImage(glide, item.url, holder.image);
}
}
e uso questi da Attività/Frammento:
loadImage(Glide.with(this), url, findViewById(R.id.image));
// or
list.setAdapter(new MyAdapter(Glide.with(this), data));
Questo ha funzionato per me durante il caricamento dell'immagine:
if (!this.isFinishing()) {
Glide.with(this)...
}
Impressionante spiegazione! Mi ha risparmiato un sacco di tempo per indagare su quale fosse la ragione principale dell'eccezione di OOM. Grazie! – user1774316
Posso passare nel contesto del frammento ad un adattatore come 'mContext' e usare' Glide.with (mContext) ... 'nell'adattatore? – squeeish
@Terence Ovviamente, ma è uguale a 'getActivity()' quindi se si sostituisce il frammento con una transazione le risorse non verranno rilasciate fino a quando l'utente non lascerà completamente l'attività. Se hai bisogno di un 'mContext' per altri motivi (ad es.' GetString') puoi semplicemente usare 'anyView.getContext()'. – TWiStErRob