Listview项目在用户滚动时从内存中删除位图

时间:2013-01-09 15:21:13

标签: android listview

我正在开发一个Android应用程序。我有一个包含列表视图的活动。

列表视图包含许多项目,每个项目都包含一个位图图像。

因为列表非常大并且包含大量图像,所以在加载位图时,某些旧设备会出现内存错误。

所以我正在寻找一种方法来为旧设备执行以下操作:

  • 加载视图中(或靠近它)的项目的位图
  • 当用户向下滚动时,我会加载应该显示给他的位图并删除现在隐藏的位图
  • 因此,任何时候只有视图中(或附近)的图像被加载到堆中,而当其他图像不再在视图中时被删除。

有办法吗?

其他信息:

我已经按照有关如何有效加载位图图像的每条指令和代码(在android文档和我能找到的任何网站上),我也确保没有内存泄漏,我回收每个位图并确保GC工作正常,最后,在旧设备上,我尽可能地使图像的分辨率。但是列表的大小导致内存不足仍然出现在某些设备上。

所以我想知道我是否可以做上面提出的解决方案。

非常感谢您的帮助

3 个答案:

答案 0 :(得分:11)

您应该考虑从Google I / O 2012查看示例库应用程序。您需要的所有内容都在那里实现。

Video from Google I/O about gallery app

Google Code上提供了源代码,这是构建图库的一个非常好的例子。您还应该考虑查看Romain Guy的presentation(开头),在那里他解释了ListView的性能问题,并教导如何有效地使用适配器。 (ViewHolder模式和重用视图)。

这是GridView的RecycleListener(可从API级别1获得)。每当View放置在RecycleBin的废料堆内时,RecyclerListener用于接收通知。此侦听器用于释放与放置在RecycleBin中的视图关联的资源。

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.album);

    mAdapter = new PhotoAdapter(this);

    mGridView = (GridView) findViewById(android.R.id.list);
    mGridView.setAdapter(mAdapter);

    mGridView.setRecyclerListener(new RecyclerListener() {
        @Override
        public void onMovedToScrapHeap(View view) {
            // Release strong reference when a view is recycled
            final ImageView imageView = (ImageView) view.findViewById(android.R.id.icon);
            imageView.setImageBitmap(null);
        }
    });

    // Kick off loader for Cursor with list of photos
    getLoaderManager().initLoader(LOADER_CURSOR, null, mCursorCallbacks);
}

答案 1 :(得分:0)

您想搜索一些教程和示例以获取“延迟加载” 一个可能的例子是:https://github.com/thest1/LazyList

答案 2 :(得分:0)

使用像Universal Image Loader这样的库可以为缓存图像和内存管理提供选项。您应该可以通过它设置最大缓存大小,它还负责在后台线程上加载图像。

ListView负责回收您放置图像的视图,并在这方面更容易记忆。