图片加载消耗的内存
测试实验的手机及配置
一张图片700*700px 88.2k 测试手机小米k20 分辨率 1080*2340px 测试手机密度440dp
一、通过image src方式加载图片
1 | <ImageView |
1. 放入mipmap-xxxhdpi
无论设置ImageView高宽多少内存分配都是481*481*4 =925476b
这个481 是怎么来的呢
440/640 * 700 = 481.25 向上取整就是缩放转化后的高宽
2. 放入mipmap-xxhdpi
无论设置ImageView高宽多少内存分配都是642*642*4 =1648656b
手机精确密度440/ xxhdpi 对应的480dpi*原图高宽700 px = 641.6666 向上取整
二、当通过Glide裁剪图片大小的时候
无论图片放在哪个目录mdpi,hdpi,xhdpi,xxhdpi, xxxhdpi 还是网络加载
他的内存都是一样
300*300* 4 = 3600321
2
3
4Glide.with(this)
.load(R.mipmap.test_memory)
.override(300, 300)
.into(image)
1 | Glide.with(this) |
总结:
1. 当同imageView src 加载图片的情况
无论设置ImageView高宽多少,对内存分配无效。
bitmap分配的内存 =: 原图缩放的高*原图缩放的宽*每个像素大小
高宽缩放比例 :手机密度/图片所在目录对应dpi
ImageView 加载res图片过程
ResourcesImpl.java
1 | @Nullable |
设置高宽大小密度用于创建bitmap
ImageDecoder.java1
2
3
4
5
6
7
8
9// This method may modify the decoder so it must be called prior to performing the decode
private int computeDensity(@NonNull Source src) {
...
float scale = (float) dstDensity / srcDensity;
int scaledWidth = Math.max((int) (mWidth * scale + 0.5f), 1);
int scaledHeight = Math.max((int) (mHeight * scale + 0.5f), 1);
this.setTargetSize(scaledWidth, scaledHeight);
return dstDensity;
}
2. 当通过Glide裁剪本地图片大小的情况
无论图片放在哪个目录mdpi,hdpi,xhdpi,xxhdpi, xxxhdpi 还是网络加载
他的内存都是一样 : 裁剪高* 裁剪宽 * 每个像素大小
以上的所说内存分配,bitmap.getAllocationByteCount()可以获得 ,跟getByteCount 不一样
测试的图片
1 | 测试图片地址 |
不同目录对应的dpi
ldpi(低)~120dpi density=0.75
mdpi(中)~160dpi density=1
hdpi(高)~240dpi density=1.5
xhdpi(超高)~320dpi density=2
xxhdpi(超超高)~480dpi density=3
xxxhdpi(超超超高)~640dpi density=4