Reputation: 103
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;
}
}
Upvotes: 0
Views: 821
Reputation: 1778
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.
Upvotes: 1