2012-08-31 28 views
15

En Android 4.1, para mí, se produce un error aparentemente extraño en nuestra aplicación. En la aplicación, un adaptador personalizado que extiende BaseAdapter se adjunta a un widget de Galería. Cuando desplazándose hacia la izquierda a derecha y viceversa rápida consigo un FC con el mensaje de excepción:"No se pueden dibujar mapas de bits reciclados" al mostrar mapas de bits en la Galería adjunta al Adaptador

java.lang.IllegalArgumentException: mapa de bits no se puede sacar reciclado

Código para la getView (..) método es el siguiente:

@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; 
} 

Creo que debería anular la ImageView en alguna parte, pero no puedo conseguir que funcione correctamente. ImageLoader es una clase (bastante) simple para cargar las imágenes, ya sea desde LruCache, disk/sdcard o buscarlo de forma remota.

+1

podría mostrar el código de imageLoader por favor, básicamente, parece que hay algún reciclaje de un mapa de bits en su código y está tratando de mostrar el mapa de bits después (de acuerdo con el mensaje de error), pero sin el código más difícilmente puede ser dicho. – Ridcully

Respuesta

8

Resulta que este error fue causado llamando al oldBitmap.recycle() en el método entryRemoved(..) en mi clase anulando LruCache. Como el mapa de bits aún podría estar adjunto a la llamada de ImageView recycle() causará problemas.

Si entiendo correctamente: el tamaño de caché de LruCache se establecerá en su constructor. Cuando el número de elementos excede este tamaño, los objetos serán elegibles para la recolección de basura, lo que sucederá cuando el mapa de bits ya no esté asociado con un ImageView.

Muchos ejemplos y tutoriales en la web sugieren que recycle() se debe llamar al , pero por lo que puedo ver, esto es incorrecto.

+2

Sí, no es seguro suponer que puede llamar 'recycle()' desde 'entryRemoved()'. – CommonsWare

+0

Entonces, ¿cuándo llama a recycle() en su código cuando usa LruCache? – calinL

15

Recibirá este error porque no puede acceder a un mapa de bits reciclado. A medida que el sitio para desarrolladores de Android afirma:

gratuito el objeto nativo asociado con este mapa de bits, y borrar la referencia a los datos de píxeles. Esto no liberará los datos de píxeles de forma síncrona; simplemente permite que sea basura recolectada si hay no hay otras referencias. El mapa de bits está marcado como "muerto", lo que significa que lanzará una excepción si se llama a getPixels() o setPixels(), y no dibujará nada. Esta operación no se puede revertir, por lo que debe llamarse al solo si está seguro de que no hay más usos para el mapa de bits . Esta es una llamada avanzada, y normalmente no necesita ser llamada, ya que el proceso GC normal liberará esta memoria cuando no haya más referencias a este mapa de bits.

Te sugiero que no recicles el mapa de bits hasta este punto, ya que todavía hay uso para él. Así que busque en su código cuándo llama al método recycle() y luego bórrelo.

Cuando llega el punto en el que el mapa de bits no es necesario utilizar más, entonces le sugiero que utilice este método para disponer el mapa de bits:

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

espero que esto ayude.

Cuestiones relacionadas