1.加载网路图片:
假设UI设计时,以2560*1440分辨率作为基准,切图,字体大小等都是在这个基准上去做的,后台上传的图片也是如此。此时,要加载后台的一张全屏的图片(2560*1440),本文中使用Glide加载,如果不加任何处理,那么不管在什么屏幕上,加载的都是原图,如解码格式为:PREFER_ARGB_8888,存储一像素的图片需要占用8*4bit=32/8=4byte内存,那么一张全屏的图片占用的内存大小为:2560*1440*4/1024/1024=14MB,这一算是不是吓了一跳,笔者曾经天真的以为占用内存大小和图片本身大小有关,其实图片大小只影响下载速度,为了提高加载速度可以在tinypng网站进行压缩,压缩效果还是挺惊人的。
对于分辨率没有那么大的屏幕上,如1920*1080要显示一张全屏图片只需要1920*1080的图片即可,所以,在使用的万象图片地址后面拼接上ImageView的宽高,也就是做到了控件多大,就取多大分辨率的图片,当然如果控件大于原图肯定得不到控件大小的图片,所以后台上传的图片分辨率基准就不能是小分辨率的,要尽可能的大,这样就做到了在性能和图片清晰度及加载图片速度三方面的平衡。
2.加载资源文件中的图片:
曾经很傻很天真的以为,mipmap文件夹放图片可以随便选随便放,反正不会报错,直到在将一张2560*1440的图片放到mipmap_mdpi中,然后加载直接oom才意识到问题的严重性。
首先:安卓中存放图片的文件夹有:xxxhdpi,xxhdpi,xhdpi,hdpi,mdpi,对应的手机屏幕密度为640dpi的会在xxxhdpi中取图片,如果该文件夹中没有,再去其他文件夹中选,如果只有mdpi中有,那么系统会认为mdpi是存放屏幕密度为160dpi图片文件夹,里面的图片不够我640dpi的显示使用,系统会填充(640/160)*(640/120)倍的像素然后显示出来,也就是像素提高了16倍,相应的内存占用也是原来的16倍,也就是400多MB,想想看,多么可怕的数字,很多程序系统分配的最大内存也就几百兆,这样直接OOM了。
相同的,如果我们将一张应该放到mdpi的图片放到了xxxhdpi中呢,那将会将图片压缩采样为原来的1/16,然后显示,所造成的虽然内存占用少了很多,但是图片清晰度受到了严重影响,这也是不符合规范的,所以图片存放一定要严格按照规范来。下面是不同文件对应的屏幕密度:
xxxhdpi------>640dpi
xxhdpi------->480dpi
xhdpi--------->320dpi
hdpi----------->240dpi
mdpi---------->160dpi
3.加载本地图片:
在加载本地图片时,在不同屏幕分辨率下所需要的图片也是不同的,这也就需要根据自身分辨率来对本地图片进行缩放处理然后显示,减少不必要的内存占用。
总结:对于一个需要显示大量图片的应用来说,遵循以上规则可以避免内存泄漏,并能优雅的显示图片,实现加载速度,系统性能与清晰度三方面的协调。