文档章节

Android 图片加载图片_OOM异常解决

mstian06
 mstian06
发布于 2014/07/02 16:52
字数 863
阅读 2898
收藏 11

http://stormzhang.github.io/android/2013/11/20/android-display-bitmaps-efficiently/

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错误。

本文转载自:

mstian06
粉丝 5
博文 20
码字总数 8864
作品 0
海淀
程序员
私信 提问
Afinal 0.5 发布,Android快速开发框架

Android快速开发框架Afinal已经迁移至github,地址是:https://github.com/yangfuhai/afina Afinal是一个orm、ioc框架,遵循约定大于配置原则,无需任何配置即可完成所有工作,但也可以通过配...

理工男海哥
2013/07/21
70.1K
45
android 图片加载之边下载边显示的讨论。

最近,接触的项目的图片加载都有不少的应用。大概了解了,不外乎一下几种,或者兼顾几种做法: |-采用缓存来提高用户体验,也节约流量。 |-缓存上做文章,采用多种策略的缓存模式,来达到更加...

Justin_Chiang
2013/12/25
1K
7
Android高效加载大图、多图解决方案,有效避免程序OOM

高效加载大图片 我们在编写Android程序的时候经常要用到许多图片,不同图片总是会有不同的形状、不同的大小,但在大多数情况下,这些图片都会大于我们程序所需要的大小。比如说系统图片库里展...

工作日
2013/08/26
236
1
Android:内存控制及OOM处理

OOM(内存溢出)和Memory Leak(内存泄露)有什么关系? OOM可能是因为Memory Leak,也可能是你的应用本身就比较耗内存(比如图片浏览型的)。所以,出现OOM不一定是Memory Leak。 同样,Mem...

Xushao
2013/05/07
840
1
QQ或者微信客户端如何实现加载本地图片的?

QQ或者微信客户端,大家熟悉的android版客户端,它里面有获取本地图片的列表,非常流畅并且非常稳定。大家知道,手机内存有限,加载大量图片务必考虑内存问题,我在实现获取本地图片的过程中...

龙印在天
2015/03/05
516
7

没有更多内容

加载失败,请刷新页面

加载更多

Kafka再平衡机制详解

所谓的再平衡,指的是在kafka consumer所订阅的topic发生变化时发生的一种分区重分配机制。一般有三种情况会触发再平衡: consumer group中的新增或删除某个consumer,导致其所消费的分区需要...

爱宝贝丶
25分钟前
21
0
element 验证 请输入大于0的整数

data() { var validatePass = (rule, value, callback) => { // if (value <= 0) { // callback(new Error('请输入大于0的整数')); // } else { // c......

沉迷代码我爱学习
36分钟前
4
0
报表工具花钱or开源?我对比了这6个工具

近一年都在处理报表问题,调研了不少报表工具,也开发了适合公司业务的报表应用。分享一些关于如何选择报表工具的个人观点,希望对你有参考作用。 对于大部分企业来说,能花时间和人力去开发...

帆软
37分钟前
3
0
自建redis笔记--Redis cluster搭建

Redis cluster搭建 2018年十月 Redis 发布了稳定版本的 5.0 版本,推出了各种新特性,其中一点是放弃 Ruby的集群方式,改为 使用 C语言编写的 redis-cli的方式,是集群的构建方式复杂度大大降...

北极之北
37分钟前
3
0
分享一个在caffe中实现的yolo层

这是别人实现的,是我移植到cc的cpu实现,可以实现caffe中使用yolo3,但是我感觉实际效果不如darknet 好点 template <typename Dtype>inline Dtype sigmoid(Dtype x){return 1. / (1. ...

开飞色
39分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部