Android 图片加载优化

来源:互联网 发布:mysql全国地区数据库 编辑:程序博客网 时间:2024/05/17 00:12

Android中通过Bitmap对象来使用图片,在加载Bitmap对象的时候,可能会导致UI线程被阻塞,用户体验差或者ANR问题;Bitmap对象迅速的消耗掉大量的内存,出现OutOfMemory异常等问题。在Android应用在加载Bitmap的时候,由于以下原因,我们需要特别的小心处理:

1.移动设备的内存资源有限,我们应该尽量的提高内存的使用效率,避免耗尽内存导致程序崩溃。

2.Bitmap对象会消耗大量内存。图片在以文件的形式存储时,可能会很小,但是当其以Bitmap的形式加载进内存的时候,将会占用大量内存,其计算公式为

 图片长度像素数*图片宽度像素数*每像素需大小,即与图片的分辨率和Bitmap配置有关。

从Android 2.3开始,使用ARGB_8888作为Bitmap的默认配置,该配置下,每个像素需要使用4Byte来表示。以我手机拍摄的一张照片为例,其分辨率为 4160*2340,大小为5.89M,当其加载进内存的时候,需要4160*2340*4/1024/1024 约为37.13M(Bitmap对象还需要保存一些关于图片的数据信息),由此可见,Bitmap对象对内存的消耗是非常巨大的。

3.在Android应用中,我们可能会在UI中同时加载多张图片,如ListView,GridView,ViewPager等

因此,我们需要对Bitmap的使用保持谨慎


在Android加载图片的过程中,我们通常使用多种优化手段来提高内存的使用效率,改善用户体验,一般来说有以下方法:

1.高效加载大图

2.在非UI线程处理Bitmap对象

3.缓存Bitmap

4.管理Bitmap的内存使用


1.高效加载大图

一般情况下,我们需要加载的图片的分辨率都会超过我们需要呈现的大小很多,例如,现在手机的摄像头1300万像素已经是标配了,其拍摄的照片的分辨率远远超过了手机屏幕的分辨率。加载一个超过屏幕分辨率的照片没有什么显而易见的好处,除非我们有特别的需求,而且这将会浪费大量的内存资源,甚至导致耗尽内存。通常我们通过对图片的缩放来获取一个与UI控件大小匹配的低分辨率的照片来进行显示。这将会大大的降低对内存的消耗,而且也不会降低用户的体验。

BitmapFactory提供了一些decode方法(decodeFile(),decodeStream(),decodeResource(),decodeByteArray())来从不同的资源中创建Bitmap,这些方法在创建Bitmap的时候会尝试分配内存,因此容易导致OOM异常的发生。因此,在通过这些方法进行解码的时候,我们可以传递一个BitmapFactory.Options对象,来指定一些设置,从而避免直接进行内存分配,同时获取图片的分辨率以及类型信息。


在获取了图片的分辨率信息之后,我们就可以判断是加载完整的图片还是加载一个低分辨率的版本,我们需要考虑:
. 加载完整图片所需要的内存
. 程序加载图片所需要的其他内存需求
. 展示这张图片的控件的大小
. 屏幕大小与屏幕密度
例如,在一个100*100的控件上面,我们完全没有必要去加载一个1024*768图片的完整版本,我们只需要加载一个低分辨率的版本即可。我们可以在解码的时候,通过设置BitmaoFactory.Options的inSampleSize的值来指定缩放的比例。例如一个分辨率4160*2340的照片,我们可以设置inSampleSize的值为4,来获得一个宽和高都为原来的1/4的低分辨率的照片,大约为1040*585。加载完整版本的图片需要37.13M,设置inSampleSize值为4后,需要的内存将为原来的1/16(Bitmap配置都使用ARGB8888的情况下)。我们可以根据具体的需要,来计算恰当的缩放比例。

注意:缩放的值一般设置为2的幂数,因为对于非 2的幂数的值,解码器还会进行进一步处理,以获取一个最接近该值的2的幂数。

inSampleSize的值最小设置为1,此时不缩放,小于1的情况下将视为1处理。


在获取到恰当的缩放比例后,我们就可以得到一个缩放后的低分辨率版本的Bitmap了



0 0
原创粉丝点击