2012-08-31 12 views
15

In Android 4.1 a, per me, si verifica un errore apparentemente strano nella nostra app. Nell'app, un adattatore personalizzato che estende BaseAdapter è collegato a un widget Galleria. Durante lo scorrimento veloce da sinistra a destra e viceversa ho un FC con il messaggio di eccezione:"Impossibile disegnare bitmap riciclati" durante la visualizzazione di bitmap nella Galleria collegata all'adattatore

java.lang.IllegalArgumentException: bitmap non può disegnare riciclata

Codice in materia di GetView (..) metodo è il seguente:

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    ViewHolder viewHolder; 

    if (convertView == null){ 
     // View is not recycled. Inflate the layout. 
     LayoutInflater vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     convertView = vi.inflate(R.layout.gallery_image, parent, false); 

     viewHolder = new ViewHolder(); 
     viewHolder.image = (ImageView) convertView.findViewById(R.id.gallery_image); 

     convertView.setTag(viewHolder); 
    } else { 
     viewHolder = (ViewHolder)convertView.getTag(); 
     viewHolder.image.setImageDrawable(null); 
    } 

    imageLoader.displayImage(images.get(position).getFilename(), 
      images.get(position).getUrlThumbnail(), 
      viewHolder.image, 
      Math.round(BitmapUtil.convertDpToPixel(400f, context)), 
      Math.round(BitmapUtil.convertDpToPixel(400f, context))); 

    return convertView; 
} 

Credo che dovrei null l'ImageView da qualche parte, ma non riesco a farlo funzionare correttamente. ImageLoader è una (abbastanza) semplice classe per caricare le immagini - sia da LruCache, disk/sdcard o recuperarlo in remoto.

+1

potresti mostrare il codice di imageLoader per favore - in pratica, sembra che ci sia qualche riciclo di una bitmap nel tuo codice e stai provando a visualizzare bitmap in seguito (secondo il messaggio di errore), ma senza il codice più difficilmente può essere ha detto. – Ridcully

risposta

8

Si è scoperto che questo errore è stato causato chiamando lo oldBitmap.recycle() nel metodo entryRemoved(..) nella mia classe sovrascrivendo LruCache. Poiché la bitmap potrebbe ancora essere collegata a ImageView chiamando recycle() causerà problemi.

Se ho capito bene: la dimensione della cache di LruCache verrà impostata nel suo costruttore. Quando il numero di elementi supera questa dimensione, gli oggetti saranno idonei per la garbage collection, che avverrà quando la bitmap non è più associata a un ImageView.

Un sacco di esempi e tutorial sul Web suggeriscono che recycle() deve essere chiamato in entryRemoved(..), ma da quello che posso vedere questo è sbagliato.

+2

Sì, non è sicuro assumere che è possibile chiamare 'recycle()' da 'entryRemoved()'. – CommonsWare

+0

Quindi quando si chiama recycle() nel proprio codice quando si utilizza LruCache? – calinL

15

Si riceve questo errore perché non è possibile accedere a una bitmap riciclata. Come il sito per sviluppatori Android afferma:

libero l'oggetto nativo associato a questa bitmap, e cancellare il riferimento ai dati dei pixel. Ciò non libererà i dati pixel in modo sincrono; semplicemente gli permette di essere garbage collection se ci sono non ci sono altri riferimenti. La bitmap è contrassegnata come "morta", vale a dire che genererà un'eccezione se si chiama getPixels() o setPixels(), e non disegnerà nulla. Questa operazione non può essere annullata, quindi è necessario chiamare solo se si è certi che non ci sono ulteriori utilizzi per la bitmap . Questa è una chiamata avanzata, e normalmente non è necessario chiamarla, poiché il normale processo del GC libera la memoria quando non ci sono più riferimenti a questa bitmap .

Suggerisco di non riciclare la Bitmap fino a questo punto, poiché è ancora in uso. Quindi cerca il tuo codice per quando chiami il metodo recycle() e poi cancellalo.

Quando il punto viene dove il bitmap non ha bisogno di essere utilizzato più, allora vi suggerisco di utilizzare questo metodo per smaltire il Bitmap:

public void disposeBitmap(Bitmap bitmap) { 
     bitmap.recycle(); 
     bitmap = null; 
} 

Spero che questo aiuta.

Problemi correlati