今天在写一个ImageLoader(自定下载加载图片类)的时候,遇到一个小问题。源起于下面两句代码:
// bitmap = BitmapFactory.decodeStream(fis);
bitmap = BitmapFactory.decodeFileDescriptor(fis.getFD(), null,mOptions);
看上去这两行代码没啥太大区别,本质都是从fis---FileInputStream文件输入流中解析一个Bitmap对象出来,但是关键在于我最开始写的时候用的被注释的那一句,结果ListView在滑动了一段时间之后,报内存不足等错误。我也觉得也奇怪,本来以为是内存泄露的问题,后来用MAT分析hprof文件,发现并没有什么泄露,而且我设定了三缓冲,到四分之一自动释放内存。
纠结了很久时间,然后把这一句改了使用mOptions,就是BitmapFactory的配置对象itmapFactory.Options。之前在加载类的时候其实是有下面三句的:
static {
mOptions.inDither = false;// 设置为false,将不考虑图片的抖动值,这会减少图片的内存占用
mOptions.inPurgeable = true;// 设置为true,表示允许系统在内存不足时,删除bitmap的数组
mOptions.inInputShareable = true;// 和inpurgeable配合使用,如果inPurgeable是false,那么该参数将被忽略,表示是否对bitmap的数组进行共享
}
但是忘记使用了,当改了:bitmap = BitmapFactory.decodeFileDescriptor(fis.getFD(), null,mOptions);之后,发现问题解决了,看样子这个options.inPurgeable=true还是很有用的。
PS:这里由于图片都是图标小图片,所以没有对bitmap的大小进行调整。
下面附上一些BitmapFactory.Options的常用选项:
BitmapFactory.Options 用于指定解码时的一些设置:
1)inBitmap如果设置,当加载内容时该方法将尝试重用这个位图;
2)inDensity使用像素密度来表示位图;
3)inDither如果存在抖动,解码器将尝试解码图像抖动;
4)inPurgeable如果设置为true,则由此产生的位图将分配其像素,以便系统需要回收内存时可以将它们清除;
5)inInputShareable与inPurgeable一起使用,如果inPurgeable为false那该设置将被忽略,如果为true,那么它可以决定位图是否能够共享一个指向数据源的引用,或者是进行一份拷贝;