0

我搜索了很多,但我无法帮助自己。有没有人可以说如何为我的 ListView 修复 OutOfMemoryError。它仅在将 50 多个位图添加到我的 ListView 后发生。我知道由于所有位图,设备内存已满,但是有没有办法回收远离视口的位图?

这是我的 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; 
    }
}
4

1 回答 1

1

您应该首先了解 ArrayAdapter 的工作原理。

当您使用 调用超级的构造函数时super(context, resource, items);,它会获取对您正在使用的集合(项目)的引用。你不需要在你的类中保留对该集合的引用。

该指令将为您提供 LinkedList 中的当前项目,该项目是要在当前视图中显示的项目:

ExtendedBitmap bitm = getItem(position);

您应该从您的集合中添加项目Activity并从那里调用notifyDataSetChanged();。ArrayAdapter 将知道该做什么。

其次,您不应该将实际位图保留在 ViewHolder 中。您应该存储位图的资源 ID 或 URL,并且只在 getView() 中获取实际的位图。

您可以使用LruCache来存放位图。然后,您将需要逻辑来尝试从 LruCache 获取位图或根据需要重新创建它(如果需要)。

希望这可以帮助。我从 Big Nerd Ranch Android 书籍中了解到这一点。

于 2013-10-16T21:31:07.790 回答