Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OutOfMemory exception appears while scrolling the list of images

I have a list of 70 text items with image icons(which are stored in drawables folder). If I launch application the first time and scroll the list slowly - the exception doesn't occur.

When the application is launched the first time and I scroll the list with 'fling' action the following exception occurs:

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)

After that, if I kill the application with DDMS, start it again and scroll it with 'fling' action, exception doesn't occur. So the exception arises only if application is installed and launched the first time.

Here is the adapter I use for the list:

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

}

Is there a way to avoid the exception? Should I catch the exception and escape the memory somehow?

Any advice how to accomplish this?

Thanks.

like image 860
k_shil Avatar asked Jan 15 '10 09:01

k_shil


1 Answers

You can't catch a java.lang.OutOfMemoryError. They're pretty much fatal.

Now, you say the problem only occurs the first time you run your application. This makes me think that the problem isn't with the view code. If a user flings a resource heavy view it can use a lot of memory, but as you say, normally your application works fine.

So - what initialisation do you do the first time you run your application? Is it possible one of the first-time run-once tasks is leaking memory meaning that there isn't enough left to use your view?

like image 162
Dave Webb Avatar answered Oct 17 '22 15:10

Dave Webb