Glide
的内存优化主要也是对Bitmap
的优化,在回答这个问题前,我们可以想想有哪些常见的Bitmap
优化手段
1.当图片大小与View
大小不一致时,可以用inSampleSize
进行尺寸优化
2.图片所占内存即宽高每像素所占内存大小,不同的模式每个像素所占的内存大小不同,我们可以利用inpreferredconfig
配置
3.Bitmpa
所占内存比较大,如果频繁创建回收Bitmap
内存可能造成内存抖动,我们可以利用inBitmap
利用Bitmap
内存
4.内存缓存,上文我们已经介绍了Glide
的弱引用缓存与LRU
缓存
其实常见的Bitmap
内存优化也就这么几种了,不过我们在工作中比较少直接使用他们。
下面我们就介绍下Glide
中具体是怎么使用他们的.
3.1 尺寸优化
当装载图片的容器例如ImageView只有100*100
,而图片的分辨率为800 * 800
,这个时候将图片直接放置在容器上,很容易OOM
,同时也是对图片和内存资源的一种浪费。当容器的宽高都很小于图片的宽高,其实就需要对图片进行尺寸上的压缩,将图片的分辨率调整为ImageView
宽高的大小,一方面不会对图片的质量有影响,同时也可以很大程度上减少内存的占用
我们通常使用inSampleSize
对Bitmap
进行尺寸缩放
如果
inSampleSize
设置的值大于1,则请求解码器对原始的bitmap
进行子采样图像,然后返回较小的图片来减少内存的占用,例如inSampleSize
== 4,则采样后的图像宽高为原图像的1/4,而像素值为原图的1/16,也就是说采样后的图像所占内存也为原图所占内存的1/16;当inSampleSize
<=1时,就当作1来处理也就是和原图一样大小。另外最后一句还注明,inSampleSize
的值一直为2的幂,如1,2,4,8。任何其他的值也都是四舍五入到最接近2的幂。
//1
int widthScaleFactor = orientedSourceWidth / outWidth;
int heightScaleFactor = orientedSourceHeight / outHeight;
//2
int scaleFactor =
rounding == SampleSizeRounding.MEMORY
? Math.max(widthScaleFactor, heightScaleFactor)
: Math.min(widthScaleFactor, heightScaleFactor);
int powerOfTwoSampleSize;
//3
if (Build.VERSION.SDK_INT <= 23
&& NO_DOWNSAMPLE_PRE_N_MIME_TYPES.contains(options.outMimeType)) {
powerOfTwoSampleSize = 1;
} else {
//4
powerOfTwoSampleSize = Math.max(1, Integer.highestOneBit(scaleFactor));
//5
if (rounding == SampleSizeRounding.MEMORY
// exactScaleFactor由各个裁剪策略如CenterCrop重写得到,详情可见代码
&& powerOfTwoSampleSize < (1.f / exactScaleFactor)) {
powerOfTwoSampleSize = powerOfTwoSampleSize << 1;
}
}
options.inSample