0

I searched so much, but i cant help myself. Is there anyone who can say how to fix OutOfMemoryError for my ListView. It only occurs after 50+ bitmaps were add to my ListView. I understand that the devices memory is just full because of all the bitmaps ,but is there a way to recycle bitmaps that are far away from the viewport?

Here is the Adapter for my ListView:

public class ImageAdapter extends ArrayAdapter<ExtendedBitmap>{
    private LinkedList<ExtendedBitmap> items;
    LayoutInflater mInflater = LayoutInflater.from(getContext());

    public ImageAdapter(Context context, int resource, LinkedList<ExtendedBitmap> items) {
        super(context, resource, items);
        this.items = items;
    }

    public void add(ExtendedBitmap bitmap)
    {
        items.add(bitmap);
        notifyDataSetChanged();
    }

    public void addFirst(ExtendedBitmap bitmap)
    {
        items.addFirst(bitmap);
        notifyDataSetChanged();
    }

    public ExtendedBitmap getBitmap(int position){
        return items.get(position);
    }

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

        if (convertView == null) { 
            convertView = mInflater.inflate(R.layout.extended_image, parent, false); ;
             holder = new ViewHolder();  
             holder.image = (ImageView) convertView.findViewById(R.id.image); 
             //holder.image.setOnTouchListener(new Touch());  
             convertView.setTag(holder); 
        }else { 
             holder = (ViewHolder) convertView.getTag(); 
        }

        holder.image.setImageBitmap(items.get(position).getBitmap());

        return convertView; 
    }
}
BigX_Jazz
  • 103
  • 3
  • 13
  • 2
    Bitmaps and out of memory issues are rife in Android. From the sidebar to the right, this appears to answer your problems: http://stackoverflow.com/questions/477572/strange-out-of-memory-issue-while-loading-an-image-to-a-bitmap-object – K5 User Oct 16 '13 at 18:53
  • they talk a little bit too general – BigX_Jazz Oct 19 '13 at 12:21

1 Answers1

1

You should first learn how the ArrayAdapter works.

When you call the super's constructor with super(context, resource, items);, it gets a reference to the collection you are using (items). You don't need to also keep a reference to that collection in your class.

This instruction will give you the current item in LinkedList that is the one to be displayed in the current view:

ExtendedBitmap bitm = getItem(position);

You should add items to the collection from your Activity and call notifyDataSetChanged(); from there. The ArrayAdapter will know what to do.

Secondly, you should not be keeping the actual bitmaps in the ViewHolder. You should store the Resource ID or URL of the bitmap, and only get the actual Bitmap in getView().

You can use LruCache to house the bitmaps. Then you would need logic to attempt to get the Bitmap from the LruCache or recreate it (if needed) as it's needed.

Hope this helps. I learned about this from the Big Nerd Ranch Android book.

Rick Falck
  • 1,778
  • 3
  • 15
  • 19
  • i am using notifyDataSetChanged() in my Activity, which is working well. I gonna try to download each bitmap and store the Ressource ID in ViewHolder, but is this a usual solution for such problem? – BigX_Jazz Oct 18 '13 at 16:28
  • I am new too. I don't know what the "usual solution" is, but the BNR book was written recently, and the authors are actively answering questions on the forum for the book. If I were to write a similar app, I would consider their solution a starting point and then look into how I could improve upon it to make my implementation better. Reading through the other Q/As on the sidebar would be a good start. – Rick Falck Oct 18 '13 at 19:18
  • it seems that LruCache did it. Thank so you much for your advice! – BigX_Jazz Oct 19 '13 at 12:32