2010-01-15 9 views
5

Tengo una lista de 70 elementos de texto con iconos de imagen (que se almacenan en la carpeta de dibujos). Si abro la aplicación por primera vez y desplazo la lista lentamente, la excepción no ocurre.Excepción de OutOfMemory aparece mientras se desplaza por la lista de imágenes

Cuando se inicia la aplicación por primera vez y me desplazarse por la lista con la acción 'aventura' produce la excepción siguiente:

java.lang.OutOfMemoryError: bitmap size exceeds VM budget 
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) 
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:439) 
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:322) 
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:688) 
at android.content.res.Resources.loadDrawable(Resources.java:1710) 
at android.content.res.Resources.getDrawable(Resources.java:585) 

Después de eso, si mato a la aplicación con DDMS, empezar de nuevo y de desplazamiento con la acción 'fling', la excepción no ocurre. Entonces, la excepción surge solo si la aplicación se instala y se inicia por primera vez.

Aquí es el adaptador que uso para la lista:

public class AuthorAdapter extends ArrayAdapter<Author> { 

private ArrayList<Author> items; 
private Context context; 
private LayoutInflater inflater; 

public AuthorAdapter(Context context, int textViewResourceId, ArrayList<Author> items) { 
    super(context, textViewResourceId, items); 
    this.items = items; 
    this.context = context; 
    inflater = LayoutInflater.from(this.context); 
} 

static class ViewHolder { 
    ImageView authorFace; 
    TextView authorName; 
    TextView authorWho; 
} 

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

    ViewHolder holder; 

    if (convertView == null) { 
     convertView = inflater.inflate(R.layout.autor_data, null); 

     holder = new ViewHolder(); 
     holder.authorFace = (ImageView) convertView.findViewById(R.id.authorFaceImageView); 
     holder.authorName = (TextView) convertView.findViewById(R.id.authorNameTextView); 
     holder.authorWho = (TextView) convertView.findViewById(R.id.authorWhoTextView); 
     convertView.setTag(holder); 
    } else { 
     holder = (ViewHolder) convertView.getTag(); 
    } 

    Author author = items.get(position); 
    if (author != null) { 
     if (holder.authorFace != null) { 
      String faceFileName = author.getFace(); 
      String facePlaceName = context.getPackageName() + ":drawable/" + faceFileName.subSequence(0, faceFileName.lastIndexOf(".")); 
      int faceFileId = context.getResources().getIdentifier(facePlaceName, null, null); 
      holder.authorFace.setImageResource(faceFileId); 
     } 
     if (holder.authorName != null) { 
      holder.authorName.setText(author.getName()); 
     } 
     if (holder.authorWho != null) { 
      holder.authorWho.setText(author.getWho()); 
     } 
    } 
    return convertView; 
} 

}

¿Hay una manera de evitar la excepción? ¿Debo atrapar la excepción y escapar de la memoria de alguna manera?

¿Algún consejo sobre cómo lograr esto?

Gracias.

+0

¿Qué tan grandes son sus imágenes? –

+0

Las imágenes de los elementos de la lista son de aproximadamente 3 KB cada una. Uso dos actividades (principal y lista). Las imágenes de fondo de la actividad son de aproximadamente 60 KB cada una. También hay imágenes que uso para controles de UI, alrededor de 100 KB en total. ¿Puede ser un problema de simulador? Lamentablemente, no puedo probar mi aplicación en el dispositivo en este momento. – Zzokk

Respuesta

3

No se puede tomar un java.lang.OutOfMemoryError. Son bastante fatales.

Ahora, usted dice que el problema solo ocurre la primera vez que ejecuta su aplicación. Esto me hace pensar que el problema no es con el código de vista. Si un usuario arroja una vista pesada de recursos puede usar mucha memoria, pero como dices, normalmente tu aplicación funciona bien.

Entonces, ¿qué inicialización hace la primera vez que ejecuta su aplicación? ¿Es posible que una de las primeras tareas de ejecución una vez gotee memoria lo que significa que no hay suficiente para usar su vista?

+0

En realidad, no inicializo ninguna imagen cuando comienzo la aplicación. Todas mis imágenes se almacenan en la carpeta de dravable. Solo configuro el adaptador para la lista. En el método getView() del adaptador, configuro la imagen para cada elemento de la lista (consulte el código anterior): holder.authorFace.setImageResource (faceFileId); Según tengo entendido, se llama al método getView() cada vez que se muestra un elemento de la lista en la pantalla del teléfono. Probablemente cuando me desplazo rápidamente por la lista, la memoria caché no tiene tiempo para reciclar. Cuando me desplazo lentamente por la lista, no se observa ninguna excepción. – Zzokk

+2

Me preguntaba si hay algún otro comportamiento de inicialización que esté perdiendo memoria por lo que no hay espacio en el montón para muchas imágenes cuando desplaza rápidamente su vista. Esto explicaría por qué el problema solo ocurre la primera vez que ejecuta su aplicación. –

+1

De acuerdo con Dave, empezaría a ver qué haces la primera vez que inicias la aplicación en comparación con el inicio normal. Te estás agarrando a algo grande durante tu primer inicio de la aplicación. –

Cuestiones relacionadas