andorid 图片加载总结

本文详细探讨了Android中图片加载的关键技术,包括BitmapFactory的不同使用方式及其对图片尺寸的影响,图片加载到内存中的实际大小计算方法,以及如何进行有效的内存优化。此外,还介绍了图片异步加载的基本原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

andorid图片加载总结


1.BitmapFactory的两个方法decodeFile和decodeResource的区别
decodeFile读取内部存储或者外部存储中的图片,得到的图片尺寸是原始尺寸
decodeResource读取res或者raw目录下的图片,得到的图片尺寸是原始尺寸*缩放系数(inTargetDensity/inDensity)


在不使用BitmapFactory.Options的情况下
这个缩放系数可用由BitmapFactory.Options中的属性来改变,默认情况下inScale为true,inDensity为160
如果inScale为false则不进行缩放
如果图片放在没有dpi的目录下,inDesity即为默认值160,inTagetDensity是设备屏幕密度,如果是480,那么得到的图片尺寸长和宽各乘以3
而如果放在了带dpi的drawable目录下,其inDensity会不同,ldpi 120  mdpi 160  hdpi 240 xhdpi 320 xxhdpi 480 


2.一张图片加载到内存中到底有多大
Bitmap的内存有大多
获取res中的图片资源无论是通过BitmapFactory的decodeResource还是getDrawable最终都是调用了BitmapFactory.decodeResourceStream
所以一张图片加载到内存中的大小实际上就是内存中Bitmap的大小


理论上一张图片所占的内存是width*height*bpp
bpp由像素格式决定
ARGB8888 bpp = 4
ARGB4444 bpp = 2
RGB565   bpp = 2
ALPHA_8  bpp = 1


但是这个理论值有个前提, 读取图片使用的是decodeFile或者是没有放在drawable或者raw目录下的图片,会以图片原大小读到内存中,如果没有这个前提,图片会根据inDesity和设备屏幕的Density进行缩放
所以,图片放在不同dpi目录下,Bitmap的内存是不一样的,但是并不是说放到高dpi目录下越好,虽然内存减少了但是图片被放大了,图片可能出现马赛克


3.图像内存优化
(1)android 3.0之前Bitmap的像素数据保存在Native堆中,而Bitmap对象保存在Java堆中,3.0之后都放在Java堆中,在确定Bitmap不再使用以后及时调用recyle来回收Native堆中的内存,并将Bitmap对象置为null
(2)缓存通用的Bitmap,通常在列表型的数据中,图片会有默认图片
(3)加载大图时,使用BitmapFactory的decode方法时,应该使用图片缩放,防止发生OOM
使用BitmapFactory.Options的inJustDecodeBounds为true首先获取图像实际大小,但是并不会将图片读到内存中
然后和控件大小计算中缩放比例,将inSimpleSize设置为缩放比例
(4)读取图像时try catch不能只捕获Exception而应该捕获OutOfMemoryError
(5)LruCache最近最少使用算法,内部使用LinkedHashMap,但是LruCache只是用强引用并没有使用软引用,实际项目中可以增加软引用以更高效地利用缓存


4.图片异步加载
android对UI的更新在UI线程中进行,如果UI线程做了耗时操作,会引起卡顿甚至ANR
通常加载网络图片和SD中图片时会使用异步加载,在工作线程中将图片加载到内存中,然后通知主线程来更新和绘制UI
不能闭门造成,要善于借用轮子
android有很多优秀的开源图片加载库
UniversalImageLoader
Volley
picasso
Glide
Fresco
各有各的好,有的从网络优化,有的从内存优化,有的从适用性更广
但是基本的原理都差不多
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值