listview gets out of memory exception, but with no memory leaks?

前提是你 提交于 2019-11-29 14:55:26
Joe

The comment from Tim is spot on. The fact that your code does not utilize convertView in its BaseAdapter.getView() method and keep inflating new views every time is the major cause of why it will eventually run out of memory.

Last time I checked, ListView will keep all the views that are ever returned by the getView() method in its internal "recycle bin" container that will only be cleared if the ListView is detached from its window. This "recycle bin" is how it can produce all those convertView and supply it back to getView() when appropriate.

As a test, you can even comment out the code portion where you assign an image to your view:

                // final int imageResId = field.getInt(null);
                // imageView.setImageResource(imageResId);

And you will still get the memory allocation failure at one point :)

There are two points your code:

  1. As mentioned by previous answers, you are trying create so many new objects, well, that's the main reason of OutOfMemory problem.

  2. Your code is not efficient enough to load all objects continuously (like swipe up/down for scrolling), well, it's lagging.

Here a hint to fix those two common problems:

Field field = fields[position % fields.length];
View v = convertView;
ViewHolder holder = null;

if (v == null) {
    v = inflater.inflate(R.layout.list_item,null);
    holder = new ViewHolder();
    holder.Image = (ImageView) inflatedView.findViewById(R.id.imageView);
    holder.Text = (TextView)inflatedView.findViewById(R.id.textView);
    v.setTag(holder);
} else {
    holder = (ViewHolder) v.getTag();
}
return v;

This is the simple ViewHolder for efficient ListView.

static class ViewHolder {   
    ImageView Image;
    TextView  Text;
}

Pretty much simple but very effective coding.

Your catching Exception e, but OutOfMemoryError is Error, not an Exception. So if your want to catch OutOfMemory your can write something like

catch(Throwable e){}

or

catch(OutOfMemoryError e){}

I have been getting oom error for a long time, when I inflate my listview with too many images (even though the images were already compressed)

Using this in your manifest might solve your issue:

android:largeHeap="true"

this will give your app a large memory to work on.

Use this only when there are no alternate ways for your desired output!

To Know about the drawbacks of using largeHeap check this answer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!