GridView di immagini con ViewHolder più lenta che senza

  • Risposte:1
marcello
  • Post del forum: 16

28 mag 2015, 15:19:42 Tramite pagina web

Salve a tutti, sono alla mia prima app (come forse avrete notato, con tutte le domande che ho già inserito in questo forum) e quindi per ogni problema sbatto la testa contro il muro finché non mi decido a chiedere aiuto.

Ho una GridView con immagini, e vorrei implementare il ViewHolder per migliorare le performance. Di seguito il codice.

XML per le dimensioni della singola cella della griglia:

<ImageView
        android:layout_width="wrap_content"
        android:layout_height="@dimen/grid_view_item_height" 
android:id="@+id/immagineGriglia" />

e il codice java dell'image adapter:

import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.ArrayList;

public class ImageAdapterAdulti15 extends ArrayAdapter {
    private Context context;
    private int layoutResourceId;
    private ArrayList data = new ArrayList();

        // Keep all Images in array
    public Integer[] mThumbIds = {
            R.drawable.image1, R.drawable.image2........
    };

    // Constructor
    public ImageAdapterAdulti15(Context context, int layoutResourceId, ArrayList data) {
        super(context, layoutResourceId, data);
        this.layoutResourceId = layoutResourceId;
        this.context = context;
        this.data = data;
    }

    @Override

    public View getView(int position, View convertView, ViewGroup parent) {
        View cella = convertView;
        ViewHolder holder = null;

        if (cella == null) {
            LayoutInflater inflater = ((Activity) context).getLayoutInflater();
            cella = inflater.inflate(layoutResourceId, parent, false);
            holder = new ViewHolder();
            holder.immagineGriglia = (ImageView) cella.findViewById(R.id.immagineGriglia);
            cella.setTag(holder);
        } else {
            holder = (ViewHolder) cella.getTag();
        }

        ImageItem item = (ImageItem) data.get(position);
        holder.immagineGriglia.setImageBitmap(item.getImage());
        return cella;
    }

    static class ViewHolder {
        ImageView immagineGriglia;     
    }     
}

Come dicevo nel titolo, in questo modo la GridView risulta più lenta e con più tendenza a piantarsi per OutOfMemoryError rispetto alla stessa griglia senza ViewHolder.
Direi quindi che il codice di cui sopra è sbagliato o incompleto.
Sto avendo davvero difficoltà a capire non tanto il concetto di ViewHolder, quanto piuttosto il codice per farlo funzionare. Sapreste mica dirmi dove sbaglio?
Grazie!

Rispondere
marcello
  • Post del forum: 16

29 mag 2015, 13:43:32 Tramite pagina web

Ho provato a modificare questa riga del codice in questo modo:

ImageItem item = (ImageItem) data.get(position);
 holder.immagineGriglia.setImageDrawable(context.getResources().getDrawable(mThumbIds[position]));
 return cella;

Ora la gridView scorre più fluida, ma mi sembra che causi qualche memory leak.
ogni immagine è cliccabile, e il tocco porta a una pagina con una versione ingrandita e zoomabile della stessa immagine.
Se tocco un'immagine funziona, ma dopo un po' di chiudi-apri-chiudi-apri si pianta. OutOfMemoryError.

Su alcuni device, addirittura, (sto provando con diversi device emulati da Genimotion e due cellulari reali) non si apre proprio l'activity con la gridView, si pianta prima.
Potrebbe essere un problema di memory leak? E' un argomento che per me è ancora abbastanza misterioso...
Come posso capire dove sta il problema? So che esiste un'estensione per Eclipse per verificare l'uso della memoria, c'è qualcosa per Android Studio, visto che per il momento ho imparato a usare quello e vorrei evitare, almeno inizialmente, di incasinarmi ulteriormente imparando a usare un altro programma?

Rispondere