Android-GC滞后于列表视图滚动;“更大”;图像

Android-GC滞后于列表视图滚动;“更大”;图像,android,image,listview,garbage-collection,lag,Android,Image,Listview,Garbage Collection,Lag,在listview中,我想在列表项上绘制一个图像。 这20幅图像必须缩放以在垂直模式下填充宽度。 手机分辨率为480 x 800像素(SGS2)。 图像分辨率为400x400,大小约为100KB。 我已将图像放置在可绘制文件夹中 当我在列表中滚动时,它不会平滑 我了解一些事情: -应用程序堆大小=有限,第一次运行时分配=13MB,剩余1MB。 -我有GC_FOR_ALLOC日志消息,这会使系统停止15毫秒。(我想这是我在滚动方面的滞后)。 -更改代码后,我还会看到GC_并发消息 有了这些GC消息

在listview中,我想在列表项上绘制一个图像。 这20幅图像必须缩放以在垂直模式下填充宽度。 手机分辨率为480 x 800像素(SGS2)。 图像分辨率为400x400,大小约为100KB。 我已将图像放置在可绘制文件夹中

当我在列表中滚动时,它不会平滑

我了解一些事情: -应用程序堆大小=有限,第一次运行时分配=13MB,剩余1MB。 -我有GC_FOR_ALLOC日志消息,这会使系统停止15毫秒。(我想这是我在滚动方面的滞后)。 -更改代码后,我还会看到GC_并发消息

有了这些GC消息,我知道每当我滚动到一个新的listview条目中的另一个图像时,我的垃圾收集就会启动。 到目前为止,我可以对此进行分析,但我不知道如何永久地修复和删除GC。 我已经将图像缩小到100x100,它将GC消息延迟更长的时间。 但最终GC开始起作用。 我使用convertview回收视图,并且已经在视图中使用了保持器

我读过关于重新使用图像内存的文章,但不确定是否以及如何做到这一点。 或者,在listview中使用这些较大的图像可能是“正常”的,我需要重新考虑图像的绘制,并且只在旋转结束时才开始绘制

我应该使用Listview来滚动图片吗

2012-12-31_02:11我已经实现了setOnScrollListener,它可以使滚动平滑。 我认为这是一段代码,我必须进一步研究,以拍马屁


列表视图适配器
listview XML
您一直在打开
位图,这些位图占用了大量内存,需要收集这些内存,以便有足够的空间存放下一次加载的大量
位图

如果加载图像不以全尺寸显示,则可以使用
BitmapFactory
选项对其进行子采样。这样,您只需要占用填充视图所需的内存,从而减少GC调用


您还可以尝试在适配器中保留某种缓存,以避免每次重新加载位图。

有许多技术可以加快列表视图的速度。看见您应该回收视图,这将减少垃圾收集。在列表滚动停止之前,您也可以考虑不要加载图像,请参阅

谢谢您这样引导我。我将尝试解决这个问题,并尽快给出反馈。我试着把图像缩小一些作为我的显示分辨率。Image=400x400,display=480 x 800,但我还是想知道在调整图像大小时会进行哪些内存优化。我发现使用BitmapFactory时,图像的大小调整并不是问题所在。所以我继续检查缓存的可能性和“回收”(不确定我是否已经这样做了)。或者是充气机解决了这个问题?我正在阅读图像的惰性加载,但我认为这会给我一个真正的惰性解决方案,我不会学到这么多。现在我正在调试和学习一些小的调整,其他人可以阅读并再次学习。如果我错了,请纠正我。我相信你对OnScrollListener的观点是我需要的部分。由于图像是“大的”(400x400px),我想我总是能得到GC的支持。经过阅读和实验,我了解到没有适合每个人的工具。通过实验不同的代码片段,延迟加载是一个很好的开始。
public class ListviewAdapter extends BaseAdapter {

    private static Activity activity;
    private int[] data;
    private static LayoutInflater mInflater = null;

    public ListviewAdapter(Activity a, int[] d) {
        activity = a;
        data = d;
        mInflater = (LayoutInflater) activity
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    public int getCount() {
        return data.length;
    }

    public Object getItem(int position) {
        return position;
    }

    public long getItemId(int position) {
        return position;
    }

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

        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.listviewitem, parent,
                    false);
            holder = new ViewHolder();

            holder.picture = (ImageView) convertView.findViewById(R.id.image);
            convertView.setTag(holder);

        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        if (!MainActivity.isScrolling) {
    holder.picture.setImageResource(data[position]);
    }

        return convertView;
    }

    static class ViewHolder {
        ImageView picture;
    }

}
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content">
  <ImageView
      android:id="@+id/image"
      android:src="@drawable/stub"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:contentDescription="Animal images"
        android:scaleType="fitCenter"
        android:scrollingCache="false"
        android:animationCache="false" 
        />

</LinearLayout>