Android 图片加载优化
2015-06-01 10:21
274 查看
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的内存使用
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了
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了
相关文章推荐
- Android Fragment 真正的完全解析(上)
- 近期小结--Android系统时间获取及AVD模拟GPS相关调试
- android系统时间获取方式
- 『Android/Java』Android Studio XML Editor Preview Error:The following classes could not be found
- 使用C# + Xamarin开发Android应用-- 动态添加控件
- 给Android Studio安装Genymotion插件
- 使用C# + Xamarin开发Android 应用 -- Datetime Picker
- android广播注册简单用法
- Android中动态更新ListView
- android学到啥时候就高级了啊
- android编码相关的理解
- Android EditText 不弹出软件键盘
- Android 仿 窗帘效果 和 登录界面拖动效果 (Scroller类的应用) 附 2个DEMO及源码
- Android 界面滑动实现---Scroller类 从源码和开发文档中学习(让你的布局动起来)
- Android 实现ActionBar定制
- Android性能优化之查看GPU渲染性能
- Android 3.0之后开机无法接收系统广播权限原因
- Android性能优化之Overdraw
- android:layout_weight属性详解 (转)
- Android平台根目录文件