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错误解决办法
热度:66 发布时间:2016-04-28 05:30:19.0
相关解决方案
- jquery,二维数组取值。解决办法
- 求架构方案:一个日均访问量50万的物流筛单系统的技术架构方案?解决办法
- 关于 if(rs.getString("").trim().equals(""))解决办法
- 诡异:代码执行到哪去了?解决办法
- 关于 Spring 声明式事务管理!解决办法
- 求《Java Web 程序设计与项目实践》解决办法
- 加载Hibernate的报错了,求解。解决办法
- B/S方面,java比PHP更好吗?解决办法
- 算法求解String str = "A,B,C,A,B,A"解决办法
- 这段代码还能不能优化?解决办法
- JAVA读取一个文件,非得搞那么麻烦么?解决办法
- 求帮忙。解决办法
- POI导入excel数据(数据有父子关系)解决办法
- IE不支持JQuery吗?解决办法
- 求WebService的解决方案!解决办法
- 关于ibatis的<isNotEmpty>解决办法
- hibernate获取SessionFactory失败 咋办?解决办法
- 关于<s:iterator>遍历数据。解决办法
- ASP技术升级选择.(.net或Java)解决办法
- jsp页面提交到action,中文乱码(服务器Tomcat5.0)解决办法
- 求按钮上传~解决办法
- 在项目中META INF下创建context.xml获得mysql数据库连接池(急)解决办法
- SSH插入数据,报空指针?解决办法
- JBPM 报错,需回答,在线急等!解决办法
- 吐了,java Timer 停止不了。解决办法
- struts2 带查询条件分页怎样把值带入下一页?解决办法
- jxl导出报表时,怎样合并单元格?解决办法
- axjax与ASP的数据交换的写法?解决办法
- 怎样编写jsp登陆次数超过3次就锁定用户,再过24小时就取消锁定?解决办法
- jquey 改变匹配字符的CSS?解决办法