android 不同分辨图片放错对应文件夹会怎样?
多年前有人问过我这个问题,当时没太了解这个东西,觉得是无所谓的东西,不过没答上来这个问题还是让我记了很久。
今天又看到有人发文章讨论这个问题,我也就特意再研究下。
1,了解一下Android分辨率是什么。
2,同一个元素在不同分辨率下,应该如何准备图?
3,图片错放的情况:一,大图放小文件夹;二,小图放大文件夹。
4,Android中图片是怎么显示的。
1.Android分辨率
Android 的 res/drawable-ldpi/
、drawable-mdpi/
、drawable-hdpi/
、drawable-xhdpi/
等文件夹,本质上是给不同 屏幕密度 (dpi) 的设备提供最合适的图片资源。
ldpi ≈ 120 dpi
mdpi ≈ 160 dpi(基准)
hdpi ≈ 240 dpi
xhdpi ≈ 320 dpi
xxhdpi ≈ 480 dpi
xxxhdpi ≈ 640 dpi
系统会根据设备屏幕的 density 去选择匹配文件夹中的资源。
2. 同一个元素在不同分辨率下,应该如何准备图?
Android 的多分辨率机制就是:同一个逻辑大小 (dp),用不同像素密度的图去填充。
例如,设计稿上一个按钮是 100dp × 100dp
:
density | px 换算结果 | 应该提供的图尺寸 |
---|---|---|
mdpi (160dpi) | 100px × 100px | 100×100 |
hdpi (240dpi) | 150px × 150px | 150×150 |
xhdpi (320dpi) | 200px × 200px | 200×200 |
xxhdpi (480dpi) | 300px × 300px | 300×300 |
xxxhdpi (640dpi) | 400px × 400px | 400×400 |
这样,系统才能在不同密度下,保证 UI 逻辑大小一致,看起来一样大且清晰。
3.图片错放的情况
3.1大图放到小文件夹
如:xhdpi的图(200*200)放到了mdpi(本来只需要100*100就能满足)的文件夹,Android还是会按照图片本来的规格显示成200*200的图片,相当于用犀牛拉磨,确实有点浪费内存,但并没有使用多内存。因为你放错了,它本来解析这张200*200的图片需要多少内存还是多少,只是比100*100要用的多。
3.2小图放大文件夹
如:mdpi的图(100*100)放到了xhdpi(本来需要200*200)的文件夹,Android还是会按照图片本来的规格显示成100*100的图片,但是本文件夹是需要200*200的,会补足没有用完的内存,但是会放大图片,导致显示模糊,没有浪费内存,本来就该用200*200的,只是效果不好。
4.Android 图片显示流程
4.1. 资源目录与密度分类
Android 为了适配不同屏幕密度,把图片放在不同目录:
drawable-mdpi/
→ 160dpi(基准密度)drawable-hdpi/
→ 240dpidrawable-xhdpi/
→ 320dpidrawable-xxhdpi/
→ 480dpidrawable-xxxhdpi/
→ 640dpi
你在布局里用 @drawable/xxx
引用时,系统不会直接找“文件名”,而是根据 当前设备的屏幕密度 (dpi) 去选择最合适的资源目录。
4.2. 系统选择资源的逻辑
假设设备是 xxhdpi (480dpi),系统会按以下规则找:
首先找
drawable-xxhdpi/
,有的话直接用。如果没有,就找最接近的目录(比如
xhdpi/
或xxxhdpi/
)。找到后,如果资源和设备 density 不匹配,会自动缩放解码:
比设备密度低 → 解码时放大。
比设备密度高 → 解码时缩小。
例子:
设备是 xxhdpi (480dpi),但你只有
drawable-mdpi/
:系统会拿
mdpi
图,按 3× 放大解码。
4.3. 显示时的过程
系统 decodeResource() → 把压缩文件 (PNG/JPG/WebP) 解码成 Bitmap 像素矩阵。
如果目录和设备 density 不一致,会在这里 自动缩放像素矩阵。
这一步决定了 Bitmap 的实际像素大小,进而决定内存占用。
把 Bitmap 交给 Canvas/GPU 去绘制到屏幕上。
这时再根据 控件大小(以 dp 为单位换算 px) 进行绘制缩放。
这一阶段只影响显示效果,不改变内存。
4.4. 文件夹缺失时怎么办?
如果某个密度目录缺图,系统会这样处理:
优先找最近的目录:
例如:xxhdpi 缺图 → 系统可能用 xhdpi 图放大 1.5×,或者 xxxhdpi 图缩小 0.75×。
如果所有密度目录都没有,但
drawable/
目录(无后缀)里有 → 就用这个(不会缩放)。如果连
drawable/
都没有 → 直接报错Resources$NotFoundException
。
4.5. 特殊情况
mipmap/
文件夹:逻辑和drawable/
一样,只是 Google 推荐用来放应用图标。drawable-nodpi/
:放在这里的图片 不会被自动缩放,无论设备 density。VectorDrawable
:矢量图与 density 无关,系统会在绘制时直接放大/缩小,不存在缺失问题。
5.总结
Android 显示图片的流程:
选择资源目录 → 解码为 Bitmap(可能缩放)→ 控件绘制(可能再缩放)。文件夹缺失时:系统会自动选择最接近的 density 目录,必要时缩放 → 如果完全没有,就报错。
最佳实践:为主流 density 提供对应图(至少 mdpi、xhdpi、xxhdpi),小图标建议用 VectorDrawable,能避免内存浪费和模糊。
是需要注意别放错文件夹,但是如果总是深究这些细枝末节,就太浪费时间吹毛求疵了,技术的热爱大家各有方向,知道不代表你厉害,不知道也不代表你不行。
祝安好~