应用启动图标等系统指定图标必须用@mipmap,其余ui资源一律用@drawable;mipmap全密度保留供launcher择优使用,drawable按需加载并自动缩放。

什么时候该用 @mipmap,什么时候必须用 @drawable
只有一类资源必须走 mipmap:应用启动图标(ic_launcher、ic_launcher_round),以及系统明确要求的 launcher 相关图标,比如通知栏小图标(notification_icon)、ActionBar 图标(部分旧版适配场景)。其他所有 UI 图片——按钮背景、列表 item 图标、ImageView 内容图、Shape/XML 绘制资源——一律进 drawable。
常见错误现象:android:src="@mipmap/ic_back" 在 ImageView 中能显示,但上线后在某些设备上模糊或拉伸异常;或者你把 btn_login_bg.xml 放进 mipmap,编译直接报错“Resource not found”。
-
mipmap目录下只放 PNG/JPG 等位图,且仅限 launcher 类图标 -
drawable目录可放位图 + XML(selector、shape、layer-list等),是 UI 资源的主战场 - AndroidManifest.xml 中
android:icon和android:roundIcon的值必须指向mipmap下资源,否则桌面图标不显示
R.mipmap.xxx 和 R.drawable.xxx 在 Java/Kotlin 里不能混用
代码里引用资源 ID 时,路径和资源目录严格绑定。你把一张 arrow_left.png 放进 res/mipmap-hdpi/,那它对应的 ID 就是 R.mipmap.arrow_left;放进 res/drawable-hdpi/,ID 就是 R.drawable.arrow_left。两者完全不互通。
典型翻车现场:设计师给了一套图标,你全丢进 mipmap,写代码时却调用 iv.setImageDrawable(getDrawable(R.drawable.arrow_left)) —— 运行时直接 Resources$NotFoundException。
- XML 中用
@mipmap/xxx→ Java/Kotlin 必须用R.mipmap.xxx - XML 中用
@drawable/xxx→ Java/Kotlin 必须用R.drawable.xxx - AS 不会帮你校验这种错,编译通过,运行才崩
为什么系统坚持让 launcher 图标走 mipmap?不是为了“高大上”,是为保精度
关键区别不在“能不能用”,而在“系统怎么加载”。drawable 下的资源,系统会根据当前设备密度(如 xxhdpi)自动剔除其他密度文件夹(比如删掉 mdpi、hdpi 文件夹内容),只保留最匹配的一套,节省安装包体积;而 mipmap 下所有密度文件夹(mipmap-mdpi 到 mipmap-xxxhdpi)全部保留,哪怕你装在 xxhdpi 手机上,系统也会把 mipmap-xxxhdpi 的图标拿去渲染 launcher —— 因为桌面 Launcher App 需要自己选最合适的那一张,而不是靠系统缩放。
所以如果你把普通 UI 图标也塞进 mipmap,结果就是:安装包变大(多存了几套无用图)、运行时内存占用略高、还失去 density-aware 缩放优化(drawable 的优势)。
-
mipmap= “全密度常驻”,专供 Launcher 自主择优 -
drawable= “按需加载”,系统自动选最接近密度并缩放 - 误用
mipmap做 UI 图,不会 crash,但属于隐性浪费
XML 里写错路径,AS 不报红,但预览和真机表现可能不一致
AS 的 Layout Editor 有时会“宽容”地渲染出错的引用,比如你写了 android:background="@mipmap/btn_bg_selector"(但 selector 只能放 drawable),预览里看着正常,一跑真机就黑屏或闪退。这是因为预览走的是模拟资源解析,而运行时是真实 Resource 框架加载,后者更严格。
实操建议:只要看到 XML 属性值以 @mipmap/ 开头,立刻确认这个资源是不是 launcher 图标;只要看到 @drawable/,就默认它应该在 res/drawable* 下,且不能是纯位图以外的类型(比如 .9.png 可以,xxx.xml 也可以,但 xxx.json 就不行)。
- 检查路径:打开 Project 视图 → 切到
Android模式 → 看资源是否真在对应目录 - 验证方式:右键资源名 →
Find Usages,看有没有 XML 或代码里反向引用错位置 - 特别注意
drawable-v21、drawable-night这类限定符目录,它们仍属drawable体系,不是mipmap
mipmap 的保留策略和对 drawable 的裁剪逻辑,是编译期就决定的,一旦打成 APK 就无法动态调整。很多人改完资源目录后没 clean rebuild,导致旧缓存残留,误以为“换位置也没用”——其实只是没生效。










