Android
屏幕显示与 Bitmap
内存详解
前言
在 Android
开发中,理解屏幕显示单位和 Bitmap
内存占用是构建高效应用的基础。本文将详细介绍相关概念、计算公式及单位转换,并通过实例分析 Bitmap
在内存中的表现。
一、屏幕显示单位基础
1.1 基本单位及概念
px
手机屏幕分辨率的基本单位,与物理像素一一对应dp
密度无关像素,1dp = (屏幕密度/160)px
,用于保证不同屏幕密度下视图尺寸的一致性sp
可缩放像素,主要用于字体大小,会随系统字体大小设置变化dpi
屏幕密度,每英寸包含的像素点数,密度越大,每英寸内容纳的点数就越多ppi
每英寸像素数,由屏幕分辨率和物理尺寸计算得出的近似值
1.2 Android 密度等级
密度等级 | 密度值(dpi) | 比例 | 对应系数 | 资源目录 |
---|---|---|---|---|
ldpi | 120 | 0.75x | 0.75 | drawable-ldpi |
mdpi | 160 | 1x | 1.0 | drawable-mdpi |
hdpi | 240 | 1.5x | 1.5 | drawable-hdpi |
xhdpi | 320 | 2x | 2.0 | drawable-xhdpi |
xxhdpi | 480 | 3x | 3.0 | drawable-xhdpi |
xxxhdpi | 640 | 4x | 4.0 | drawable-xxhdpi |
二、屏幕单位计算公式与转换
2.1 基本计算公式
px
与dp
的转换:
kotlin">px = dp × (dpi ÷ 160)
dp = px × (160 ÷ dpi)
px
与sp
的转换:
kotlin">px = sp × (dpi ÷ 160) × fontScale
sp = px ÷ ((dpi ÷ 160) × fontScale)
ImageView
实际像素计算:
实际像素宽/高 =XML
中设置的dp
值 × (inTargetDensity
÷160
)Bitmap
尺寸计算:
加载后的Bitmap
宽/高 = 原始宽/高 × (inTargetDensity
÷inDensity
)
2.2 单位转换工具
kotlin">object DisplayUtils {/*** dp转px*/fun dp2px(context: Context, dpValue: Float): Int {val scale = context.resources.displayMetrics.densityreturn (dpValue * scale + 0.5f).toInt()}/*** px转dp*/fun px2dp(context: Context, pxValue: Float): Int {val scale = context.resources.displayMetrics.densityreturn (pxValue / scale + 0.5f).toInt()}/*** sp转px*/fun sp2px(context: Context, spValue: Float): Int {val fontScale = context.resources.displayMetrics.scaledDensityreturn (spValue * fontScale + 0.5f).toInt()}/*** px转sp*/fun px2sp(context: Context, pxValue: Float): Int {val fontScale = context.resources.displayMetrics.scaledDensityreturn (pxValue / fontScale + 0.5f).toInt()}/*** 获取屏幕宽度(px)*/fun getScreenWidth(context: Context): Int {return context.resources.displayMetrics.widthPixels}/*** 获取屏幕高度(px)*/fun getScreenHeight(context: Context): Int {return context.resources.displayMetrics.heightPixels}/*** 获取状态栏高度*/fun getStatusBarHeight(context: Context): Int {val resourceId = context.resources.getIdentifier("status_bar_height", "dimen", "android")return if (resourceId > 0) {context.resources.getDimensionPixelSize(resourceId)} else {0}}
}
2.3 获取设备显示信息
kotlin">fun getDisplayMetricsInfo(context: Context): String {val dm = context.resources.displayMetricsreturn """屏幕宽度(px): ${dm.widthPixels}屏幕高度(px): ${dm.heightPixels}屏幕密度(density): ${dm.density}屏幕密度DPI: ${dm.densityDpi}X轴DPI: ${dm.xdpi}Y轴DPI: ${dm.ydpi}字体缩放因子: ${dm.scaledDensity}屏幕宽度(dp): ${dm.widthPixels / dm.density}屏幕高度(dp): ${dm.heightPixels / dm.density}""".trimIndent()
}
三、Bitmap
内存计算与管理
3.1 Bitmap
内存计算公式
Bitmap
在内存中的占用大小计算公式:
kotlin">内存大小(字节) = 宽度(像素) × 高度(像素) × 每像素字节数
每像素字节数由 Bitmap.Config
决定:
配置类型 | 每像素字节数 | 说明 |
---|---|---|
ALPHA_8 | 1 | 仅存储透明度 |
RGB_565 | 2 | 无透明度通道 |
ARGB_8888 | 4 | 默认配置,最高质量 |
RGBA_F16 | 8 | 高精度浮点配置 |
3.2 Bitmap
内存大小:未压缩的原始像素数据大小
- 以一张
1920×1080
分辨率的图片为例:- 内存占用
(ARGB_8888)
:1920 × 1080 × 4 = 8,294,400 字节 ≈ 7.91 MB
- 内存占用
3.3 不同单位的内存大小表示
kotlin">fun calculateBitmapMemorySize(bitmap: Bitmap): String {val bytes = bitmap.byteCountval kb = bytes / 1024.0val mb = kb / 1024.0return """内存占用(Bytes): $bytes bytes内存占用(KB): ${String.format("%.2f", kb)} KB内存占用(MB): ${String.format("%.2f", mb)} MB""".trimIndent()
}