11

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

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

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

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

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

有没有办法做到这一点?

附加信息:

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

所以我想知道我是否可以执行上述建议的解决方案。

非常感谢您的帮助

4

3 回答 3

11

您应该考虑查看 Google I/O 2012 中的 Sample Gallery App。您需要的一切都在那里实现。

来自 Google I/O 的关于图库应用的视频

源代码可在 Google Code上找到,它是构建图库的绝佳示例。您还应该考虑查看 Romain Guy 的演示文稿(开始),其中他解释了性能问题ListView并教授如何有效地使用适配器。(ViewHolder 模式和重用视图)。

这是 GridView 的 RecycleListener(可从 API 级别 1 获得)。RecyclerListener 用于在将 View 放置在 RecycleBin 的废料堆中时接收通知。此侦听器用于释放与放置在 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);
}
于 2013-01-09T15:30:14.727 回答
0

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

于 2013-01-09T15:25:19.220 回答
0

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

ListView 负责回收您放入图像的视图,并在这方面更容易占用内存。

于 2013-01-09T16:37:10.257 回答