Android内存优化之图片占用内存优化

1、工具:

工欲善其事必先利其器,我们要优化内存就必须要有检测应用内存的工具。

a、Android Studio中自带的Android Monitors能够实时的展现应用的内存、cpu、网络、GPU的使用情况:

image

b、procrank 通过命令窗口输入adb shell procrank命令能够打印出当前设备中各个进程的内存占有情况:

image

2、影响图片解析为bitmap大小的元素:

通常我们在应用中展现一张图片,需要先把图片解析成bitmap然后在通过BitmapFactory中的一些解析方法,例如BitmapFactory.decodeByteArray(byte[] data, int offset, int length, Options
opts)其中Options中的一些属性对解析出来的bitmap的大小有影响。

a、inPreferredConfig:

图片的色彩格式,不同的色彩格式所产生的图片的效果不一样,内存的占用量也不一样,默认为ARGB_8888。

图片的色彩格式有:
ALPHA_8 :此时图片只有alpha值,没有RGB,一个像素占用一个字节
ARGB_4444:这种格式的图片,看起来质量太差,已经不推荐使用。一个像素占用2个字节,alpha(A)
值,Red(R)值,Green(G)值,Blue(B)值各站4个bites,共16个bites,即2个字节
ARGB_8888:一个像素占用4个字节,alpha(A)值,Red(R)值,Green(G)值,Blue(B)值各占8个bites,共32bites,即4个字节这是一种高质量的图片格式,电脑上普通采用的格式。
它也是Android手机上一个BitMap的默认格式。
RGB_565:一个像素占用两个字节,没有alpha(A)值,即不支持透明和半透明Red(R)值占5个bites ,Green(G)值占6个bites  , Blue(B)值占5个bites,共16bites,即2个字节. 对于没有透明和半透明颜色的图片来说, 该格式的图片能够达到比较的呈现效果, 相对于ARGB_8888来说也能减少一半的内存开销。 因此它是一个不错的选择。
所以在不要求图片透明度的情况下,我们可以通过配置使用RGB_565的色彩格式来减少图片的内存占用量。

b、Density:

在Options中有inDensity 、inScreenDensity、inTargetDensity,其中inDensity和inTargetDensity的比例会影响bitmap的大小;
inDensity即该图片自身的密度,inTargetDensity图片将要被放置到的屏幕密度,如果inDensity/inTargetDensity <1那么得到的图片将会被放大他的内存占用也会被放大,如果小于1则会被缩小,内存占用也会降低,等于1则是图片的正常内存占用。
所以我们可以通过准备多套图的方式来避免图片在解析时做的缩放从而达到视觉和内存的完美适配。
不过如果只有一套图的情况下,还想降低图片内存占用,可以在高密度的屏幕中通过适当的减少inTargetDensity来减少图片的内存占用,例如:
if(mDensity<=240){
                options.inTargetDensity =UtilImage.getDensity(context);
            }else if(mDensity>240&&mDensity<=400){
                options.inTargetDensity = (int) (UtilImage.getDensity(context)*0.8);
            }else if(mDensity>400){
                options.inTargetDensity = (int) (UtilImage.getDensity(context)*0.7);
            }

c、insample:

其实就是图片的采样,当insample=1时正常的构造图片,当insample大于1时则是取图片的1/insample*insample采样。通过增大insample可以减少图片的内存占用,不过图片的质量会降低的很严重,所以不建议使用此方法。

d、Bitmap.createBitmap:

此方法也会影响图片的内存占用,此方法本来是用来剪切图片的,但是该方法也会根据比例缩放图片,而图片的内存占用也会根据缩放比例增大缩小,但是这样做并没有改变图片的质量,所以建议不要使用该方法去放大图片,那样只是把图片的内存占用放大,而图片质量却没有变化,所以如果图片的宽高比例跟控件的宽高比例一致时,直接设置scaleType =fitXy让图片铺满整个控件即可<经测试,图片比较小时,使用拉伸铺满不会增加图片的内存>

3、如何优化图片占用内存:

<1>如果使用了内存缓存,那么尽量复用内存缓存中的图片,从而减少图片的内存占用<重要>
<2>如果不需要图片透明度使用RGB_565色彩格式解析图片
<3>使用多套图片<不同的分辨率图片,对应不同的屏幕密度>
<4>增大insample<不建议,增大insample会减少图片采样,会使图片失真>
<5>不要使用Bitmap.createBitmap去放大图片而是使用ImageView的scaleType =fitXy属性去使图片占满控件
<6>如果以上五点还是满足不了需求,那么就只能舍弃用户体验,通过检测页面状态,处于后台时就回收内存缓存。<此方案会导致用户每次打开这个页面时都会进行一次将图片解析到内存中的操作>

发表评论