资源目录的 densityDpi 与屏幕的 targetDensity
- dp : dp 是物理长度 ,大小为 1 /160 英寸 。Android 创造dp的目的是为了在不同分辨率的设备上拥有同样的物理长度(也造成了一个问题,无法解决比例适配的问题)
- density :1dp=density px
- 1080*1920:density为3.0
- 1080*2160:density为2.75
- 720*1280:density为2.0
-
densityDpi:densityDpi = density * 160 。为了计算 而产生的一个数值。
-
targetDensity :显示设备的 densityDpi,也就是DisplayMetrics 的 densityDpi
例如:红米k20pro
displayMetrics.density: 2.75 。
displayMetrics.densityDpi: 440
资源文件夹对应的 density 与DensityDpi:
资源文件夹对应的 density
Bitmap.Config
Bitmap 格式。除了尺寸外,影响一个图片占用空间还有色彩细节。位图位数越高表示可以存储的颜色信息越多,图像也就越清晰逼真。
- ALPHA_8:表示8位Alpha位图,每像素占1byte内存;
- RGB_565:表示R为5位,G为6位,B为5位,一共16位,每像素占2byte内存;
- ARGB_4444:表示16位位图,每像素占2byte内存(poor quality - Android Deprecated);
- ARGB_8888:表示32位ARGB位图,每像素占4byte内存(Recommended)。
decodeResourceStream 内存计算公式
public static Bitmap decodeResourceStream(Resources res, TypedValue value,
InputStream is, Rect pad, Options opts) {
if (opts == null) {
opts = new Options();
}
if (opts.inDensity == 0 && value != null) {
final int density = value.density;
if (density == TypedValue.DENSITY_DEFAULT) {
opts.inDensity = DisplayMetrics.DENSITY_DEFAULT;
} else if (density != TypedValue.DENSITY_NONE) {
opts.inDensity = density;
}
}
if (opts.inTargetDensity == 0 && res != null) {
opts.inTargetDensity = res.getDisplayMetrics().densityDpi;
}
return decodeStream(is, pad, opts);
}
setDensityFromOptions(bmp, opts)源码如下:
private static void setDensityFromOptions(Bitmap outputBitmap, Options opts) {
if (outputBitmap == null || opts == null) return;
final int density = opts.inDensity;
if (density != 0) {
outputBitmap.setDensity(density);
final int targetDensity = opts.inTargetDensity;
if (targetDensity == 0 || density == targetDensity || density == opts.inScreenDensity) {
return;
}
byte[] np = outputBitmap.getNinePatchChunk();
final boolean isNinePatch = np != null && NinePatch.isNinePatchChunk(np);
if (opts.inScaled || isNinePatch) {
outputBitmap.setDensity(targetDensity);
}
} else if (opts.inBitmap != null) {
// bitmap was reused, ensure density is reset
outputBitmap.setDensity(Bitmap.getDefaultDensity());
}
}
以 ARGB_8888 为例 ,一个像素占用 4个字节 。
scale = targetDensityDpi / densityDpi。
占用内存 = int(pngWidth * scale + 0.5f) * int(pngHeight * scale + 0.5f) *4(字节),