我正在使用一些类,这些类包含对Bitmap
的引用,如下所示:
class Picture {
private String localPath;
private Bitmap bitmap;
// setters and getters....
}
然后在某些片段上,我使用picture.setBitmap(BitmapUtils.decodeBitmap(picture.getLocalPath, size));
获取引用,然后将其设置为ImageView
。但我从未明确地bitmap.recycle()
或bitmap = null;
。
我不确定位图在内部如何工作以及为什么GC在某些情况下不会收集它们,所以我想知道我在做什么可能会导致内存泄漏,我该如何防止这种情况,鉴于位图引用仅作为持有者存储在对象上
编辑,因为我对Bitmap
的处理方式似乎有点混乱,我会再解释一下。信息系统中的业务模型定义了几个将图像作为属性的实体(例如,用户具有配置文件名称的配置文件和配置文件图片)。
确实如此,在这种情况下,您通常会将图片路径保留为属性而不是图片本身。但由于我从Android
相机拍摄了几张照片,我将其保存到列表中以执行批量操作。您可以看到它就像实体作为图片本身的持有者一样,因为您需要引用每张图片以对它们执行批处理操作。
答案 0 :(得分:1)
编辑回答: 我读了你编辑过的问题,我仍然相信你不应该拿着位图,我会解释原因。
我正从Android相机拍摄几张照片,我将其保存到列表中以执行批量操作。
那个“清单”,它会增长多少? 1或2张图片?好几张照片?它是无限的,只取决于用户的使用情况?
所以让我们想象一下现在非常普通的图像尺寸,即使是中档手机也有,5 MP。这是2560x1920像素,精确到4.915.200像素。如果您使用的是最优质的位图(Config.ARGB_8888
),则每个像素将占用4个字节的内存。这将导致:
4.915.200 x 4 / 1024 / 1024 (in megabytes)
因此每张图片每个位图需要 18.75兆字节的RAM空间。
我最近没有检查Android VM堆大小,但第一个ICS设备的堆大小约为48mb。这意味着您的代码加上一些图片和您的应用会抛出OutOfMemoryError
。
总结:
我仍然认为你应该只保存对摄像机生成的JPG的String
引用(如果你没有生成JPG而只获取Bitmap
,请继续保存Bitmap
{ 1}}在磁盘using this code中)然后在您的数组上排队String
,一旦您的代码到达字符串,然后您解码您的位图,进行处理,然后立即隐藏它。
原始回答:
我可能错了,但我相信你正试图重新发明轮子,你不应该。
在我看来,你正在尝试进行某种类型的位图缓存/解码,这是一个相当复杂和微妙的主题,因为它涉及线程和移动内存限制。
说我所有的建议只是使用一个已经为你处理所有这些的库。我个人最喜欢的是毕加索http://square.github.io/picasso/
有了它,你所要做的就是:
Picasso.with(context).load(path).into(imgView);
就是这样。 path
可以是您需要的任何内容,例如SD卡,URL。
答案 1 :(得分:0)
在Android 2.3.3(API级别10)及更低版本上,建议使用recycle()。如果您在应用中显示大量位图数据,则可能会遇到OutOfMemoryError错误。 recycle()方法允许应用程序尽快回收内存。
警告:只有在确定时才应使用recycle() 不再使用位图。如果您调用recycle()及更高版本 尝试绘制位图,你会得到错误:“画布:试图 使用回收的位图“。
我的建议是检查您要显示的图像数量和每个图像的大小。如果要显示大量图像,则使用像通用图像加载器这样的延迟加载库。我很少使用bitmap.recycle,因为在回收位图后,你再也不能使用它了。