Android 图片加载Bitmap OOM错误解决办法

转载 2013年12月01日 20:10:13
Android 图片加载Bitmap OOM错误解决办法
Android加载资源图片时,很容易出现OOM的错误。
因为Android系统对内存有一个限制,如果超出该限制,就会出现OOM。为了避免这个问题,需要在加载资源时尽量考虑如何节约内存,尽快释放资源等等。

Android系统版本对图片加载,回收的影响:
1,在Android 2.3以及之后,采用的是并发回收机制,避免在回收内存时的卡顿现象。
2,在Android 2.3.3(API Level 10)以及之前,Bitmap的backing pixel 数据存储在native memory, 与Bitmap本身是分开的,Bitmap本身存储在dalvik heap 中。导致其pixel数据不能判断是否还需要使用,不能及时释放,容易引起OOM错误。 从Android 3.0(API 11)开始,pixel数据与Bitmap一起存储在Dalvik heap中。

在加载图片资源时,可采用以下一些方法来避免OOM的问题:
1,在Android 2.3.3以及之前,建议使用Bitmap.recycle()方法,及时释放资源。
2,在Android 3.0开始,可设置BitmapFactory.options.inBitmap值,(从缓存中获取)达到重用Bitmap的目的。如果设置,则inPreferredConfig属性值会被重用的Bitmap该属性值覆盖。
3,通过设置Options.inPreferredConfig值来降低内存消耗:
     默认为ARGB_8888: 每个像素4字节. 共32位。
     Alpha_8: 只保存透明度,共8位,1字节。
     ARGB_4444: 共16位,2字节。
     RGB_565:共16位,2字节。
     如果不需要透明度,可把默认值ARGB_8888改为RGB_565,节约一半内存。
4,通过设置Options.inSampleSize 对大图片进行压缩,可先设置Options.inJustDecodeBounds,获取Bitmap的外围数据,宽和高等。然后计算压缩比例,进行压缩。
5,设置Options.inPurgeable和inInputShareable:让系统能及时回收内存。
      inPurgeable:设置为True,则使用BitmapFactory创建的Bitmap用于存储Pixel的内存空间,在系统内存不足时可以被回收,当应用需要再次访问该Bitmap的Pixel时,系统会再次调用BitmapFactory 的decode方法重新生成Bitmap的Pixel数组。
                        设置为False时,表示不能被回收。
      inInputShareable:设置是否深拷贝,与inPurgeable结合使用,inPurgeable为false时,该参数无意义。 
                                  True:  share  a reference to the input data(inputStream, array,etc) 。 False :a deep copy。
6,使用decodeStream代替其他decodeResource,setImageResource,setImageBitmap等方法来加载图片。
     区别: 
      decodeStream直接读取图片字节码,调用nativeDecodeAsset/nativeDecodeStream来完成decode。无需使用Java空间的一些额外处理过程,节省dalvik内存。但是由于直接读取字节码,没有处理过程,因此不会根据机器的各种分辨率来自动适应,需要在hdpi,mdpi和ldpi中分别配置相应的图片资源,否则在不同分辨率机器上都是同样的大小(像素点数量),显示的实际大小不对。
      decodeResource会在读取完图片数据后,根据机器的分辨率,进行图片的适配处理,导致增大了很多dalvik内存消耗。

       decodeStream调用过程:
             decodeStream(InputStream,Rect,Options) -> nativeDecodeAsset/nativeDecodeStream
       decodeResource调用过程:即finishDecode之后,调用额外的Java层的createBitmap方法,消耗更多dalvik内存。
             decodeResource(Resource,resId,Options)  -> decodeResourceStream (设置Options的inDensity和inTargetDensity参数)  -> decodeStream() (在完成Decode后,进行finishDecode操作)
             finishDecode() -> Bitmap.createScaleBitmap()(根据inDensity和inTargetDensity计算scale) -> Bitmap.createBitmap()

以上方法的组合使用,合理避免OOM错误。
                    

相关文章推荐

Android 图片加载Bitmap OOM错误解决办法

原文  http://fly-ever.iteye.com/blog/1941986 Android加载资源图片时,很容易出现OOM的错误。  因为Android系统对内存有一个限制,如果超出该限...

android图片加载导致的OOM分析及有效解决办法(BitmapUtils)

android应用尤其是涉及到很多图片处理的经常会遇到OOM(Out Of Memory),为什么会导致OOM,又该如何解决呢?OOM原因分析:android每一个应用都有一个独立的进程,每个进程都是...

Android 中解决图片加载OOM 之 bitmap 压缩显示,压缩上传

java.lang.OutOfMemoryError OOM就是内存溢出,即Out Of Memory。也就是说内存占有量超过了VM所分配的最大。 现在的手机照相功能强大图片的大小往往达到好几...

Android ListView,GridView,RecyclerView图片加载错位闪动问题解决办法

问题的根源还是控件的复用以及异步加载所引起的问题 解决思路: 1.使用缓存,从缓存中加载的速度大大少于从网络加载 2.设置默认图片,当一个item设置个图片然后被复用,而当前显示的图片还没有数据...

android加载大量图片内存溢出bitmap size exceeds VM budget的解决办法。

方法一: 在从网络或本地加载图片的时候,只加载缩略图。 /** * 按照路径加载图片 * @param path 图片资源的存放路径 * @param scalSize 缩小的倍数...
  • jdsjlzx
  • jdsjlzx
  • 2012年05月21日 23:16
  • 4157

android防止oom的图片加载例子

  • 2013年05月04日 22:15
  • 1.06MB
  • 下载

Android 图片加载Bit地图 OOM异常解决方法

Android 图片加载Bitmap OOM错误解决办法 Android加载资源图片时,很容易出现OOM的错误。 因为Android系统对内存有一个限制,如果超出该限制,就会出现OOM。为了避免这...

Android网络图片加载内存溢出(OOM)解决方案

将大量图片直接加载到内存中,是造成OOM的主要原因。 解决方法: 添加本地缓存,不直接从网络加载图片到内存。将图片缓存到本地,每次都从本地获取图片,如果本地没有,再从网络获取。本地缓存开启线程,将...

帧动画加载大量图片OOM的解决办法

这是在别人代码基础上更改的。 代码如下: public class SceneAnimation { /** * target imageView */ priva...

android图片加载内存优化方法,有效解决大图片内存溢出(oom)

低内存的手机如果直接加载大图片,往往会出现OOM的情况.即便是主流手机,也不能无限制的加载大图片.所以在显示图片之前,需要对图片处理,把图片缩放为最合适的尺寸再显示. 网上很大方法都是不管三七二十一,...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android 图片加载Bitmap OOM错误解决办法
举报原因:
原因补充:

(最多只允许输入30个字)