我正在开发一个Android应用程序。我有一个包含列表视图的活动。
列表视图包含许多项目,每个项目都包含一个位图图像。
因为列表非常大并且包含大量图像,所以在加载位图时,它会在某些旧设备上发出内存错误。
所以我正在寻找一种方法来为旧设备执行以下操作:
- 加载视图中(或靠近它)的项目的位图
- 当用户向下滚动时,我加载应该出现在他身上的位图 并删除现在隐藏的位图。
- 因此,在任何时候只有视图中(或附近)的图像被加载到堆中,而当其他图像不再在视图中时被移除。
有办法吗?
附加信息:
我已经遵循了有关如何有效加载位图图像的每个指令和代码(在android文档和我能找到的任何网站上),我也确保没有内存泄漏,我回收每个位图并确保GC正常工作最后,在旧设备上,我使图像的分辨率尽可能小。但是列表的大小导致内存不足仍然出现在某些设备上。
所以我想知道我是否可以做上面提出的解决方案。
非常感谢您的帮助
您应该考虑从Google I / O 2012查看示例库应用程序。您需要的所有内容都在那里实现。
来自Google I / O的关于图库应用的视频
源代码可用 谷歌代码 这是建立画廊的一个非常好的例子。你也应该考虑看看Romain Guy的 介绍 (开始)他解释性能问题 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);
}
使用类似的库 通用图像加载器 为您提供缓存图像和内存管理的选项。您应该可以通过它设置最大缓存大小,它还负责在后台线程上加载图像。
ListView负责回收您放置图像的视图,并在这方面更容易记忆。