Android中drawable和mipmap到底有什么区别

欢迎通过我的个人博客来查看此文章
老项目代码中发现有的图片放到了
drawable中, 有的图片放到了mipmap中, 开发时秉承哪个目录下文件多放哪里的原则, 偶尔有疑惑搜一搜文章, 看到了结论也就这么使用了, 不过今日有时间, 依次检验了一下文章中的内容, 发现和实际的表现出入甚远.
常见的几种结论
Case 1 drawable会剔除其它密度, mipmap会保留全部(实际上最终的结论和这个有关联)
当xhdpi密度的手机在加载apk的时候Google是有一个优化的,是会剔除drawable其他密度的文件,只保留一个基本的drawable和drawable-xhdpi的文件,而mipmap是会全部保留的。
检测方法也比较简单, 在drawable和mipmap不同密度的问价夹下分别放入同一类图片(图片标文字用于检查), 分别打包并检查其大小
Case1.1 安装包与应用大小
| 安装包大小 | 应用大小 | |
|---|---|---|
| drawable | 13.3 MB (14,016,841 字节) | 14.04MB |
| mipmap | 13.3 MB (14,017,191 字节) | 14.04MB |
结论1.1
由此可见, 虽然两个安装包大小略有差异, 考虑到图片本身的大小(每张图片都在1Mb作用), 可以认为放入drawable和mipmap文件夹中的图片在安装包和应用安装后没有差异
Case1.2 应用内表现
排除安装包的情况, 我们看一下在应用内的表现情况(通过adb shell wm density保证只修改手机的dpi信息)
| 100 | 420 | 800 | |
|---|---|---|---|
| drawable | ![]() |
![]() |
![]() |
| mipmap | ![]() |
![]() |
![]() |
结论1.2
由此可见, 文件不论放在哪个目录下, 在手机中都会正确的显示为其匹配的图片资源
Case 1.3 应用内缩放
如果一个 imageView 有缩放动画,使用 drawable 下的图片,会一直使用一张来缩放图片实现 imageView 缩放动画。
如果使用 mipmap 下的图片,会根据缩放程度自动选择比当前分辨率大而又最接近当前分辨率的图片来做缩放处理。
这个可能大家见得不是很多, 不过既然有这种说法, 那就来测试一下
drawable
| 小缩放比例 | 大缩放比例 |
|---|---|
![]() |
![]() |
mipmap
| 小缩放比例 | 大缩放比例 |
|---|---|
![]() |
![]() |
结论1.3
可以看到在缩放动画的过程中, 一直显示的都是同一个动画
Case 2 应用内性能
Google对mipmap的图片进行了性能优化, 使其可以表现的更好
drawable
| 性能检查一览 | MEMORY | 10次图片加载平均时间 |
|---|---|---|
![]() |
![]() |
146 |
mipmap
| 性能检查一览 | MEMORY | 10次图片加载平均时间 |
|---|---|---|
![]() |
![]() |
151 |
结论2
可以看到, 加载单张图片的情况下其性能基本一致,不排除图片太小/太少性能优化不明显的情况, 不过尝试单证图片重复加载的情况下依旧表现为性能相近的情况, 或许时只针对特殊类型有优化? 如各位知道的更详细, 欢迎和我进行交流.
Case3 启动图标
在查阅资料的时候, 发现多次提及minmap应用只放入应用的启动图标, 使其可以得到优化.
| 100dpi | 420dpi | 800dpi | |
|---|---|---|---|
![]() |
![]() |
![]() |
结论3
可以看到, 不同dpi的情况下应用图标的显示情况都是一致的. 其应用图标切换的边界值也是一致的.
关于420dpi和800dpi显示效果一样的情况, 因为种种原因, 应用图片在选择图片资源的时候, 需要将密度扩大25%左右[1].
看到这里大家应该和我有着一样的疑惑, 既然drawable和mipmap下图片的表现不论是安装包还是应用内, 甚至连官方文档都这么说了, 为什么各种测试结果下来, 两者的表现基本的一致呢?
罪魁祸首 Bundle(.aab)
提到Bundle(.aab)国内的开发者可能都比较陌生, 甚至不少之前做过Google Play上架应用的都不是很熟悉. 这个其实在我们每次手动打包的时候都会出现.

简单来说.aab包一般用于Google Play商店使用, 在你从Google Play商店下载应用时, 它会根据你手机的实际使用情况来下载不同drawable中的资源. 以期望达到减少安装包大小的目的. (一般情况下手机dpi不会改变, 其它密度下的资源文件直到应用卸载时都不会被使用).
下面的测试使用到的工具为bundletool[2], 简单来说, 就是模拟从Google Play下载应用和安装应用的过程.
安装包比较
| 安装包(apks)大小 | 应用大小 | |
|---|---|---|
| drawable | 5.91 MB (6,201,543 字节) | 6.22MB |
| mipmap | 12.6 MB (13,230,670 字节) | 13.26MB |
应用内表现
| 100 | 420 | |
|---|---|---|
| drawable | ![]() |
![]() |
| mipmap | ![]() |
![]() |
可以看到, 当图片放到drawable相关文件夹下的时候, 通过.aab包安装的应用会比放到minmap的下的应用小许多, 并且应用内更改dpi的时候页可以看到其不再能自动根据当前dpi选择对应的图片了. |
结论
那么通过以上的测试, 我们可以得到以下结论了
以下结论均不涉及mipmap的性能优化相关(主要是暂未能设计好一个比较明确的测试对比)
以下测试机型为pixel 7, 测试Android版本为13
- 当应用构建为.apk的情况下,
drawable和mipmap文件夹下的资源表现无差异, 不论是应用内表现还是在启动器(应用图标)中表现. - 当应用构建为.aab的情况下,
drawable文件夹下的资源会寻找匹配的设备密度保留, 不匹配的资源会被删除已保证apk的大小.而mipmap文件夹下的资源文件会全部被保留.
那么我们应用内使用的图片就可以放到任意的目录下么?
如果你的应用是通过.apk分发安装的, 原则上是没有区别的. 但是Google对相关的目录也有推荐说明:
可以看到, mipmap目录下原则上只能保存应用图标. 同样, 其官方项目及单密度资源项目也都是这样使用设计这两个文件夹的.
.aab包内mipmap保留机制是否是只适用于应用图标
测试后可以发现, mipmap的保留机制适用于mipmap下所有的图片资源, 不论是否为应用图标
相关代码可以访问我的GitHub
Android中drawable和mipmap到底有什么区别的更多相关文章
- Android中Intent传值与Bundle传值的区别详解
Android中Intent传值与Bundle传值的区别详解 举个例子我现在要从A界面跳转到B界面或者C界面 这样的话 我就需要写2个Intent如果你还要涉及的传值的话 你的Intent就要写两 ...
- android 中theme.xml与style.xml的区别
from://http://liangoogle.iteye.com/blog/1848448 android 中theme.xml与style.xml的区别: 相同点: 两者的定义相同. <r ...
- Android中Drawable知识总结
本文是学习<Android开发艺术探索>中Drawable章节之后的一个总结. 一.常见的Drawable种类介绍 Drawable类 xml标签 描述 BitmapDrawable 表示 ...
- Android中Drawable分类汇总(上)
Android把可绘制的对象抽象为Drawable,不同的图形图像资源就代表着不同的drawable类型.Android FrameWork提供了一些具体的Drawable实现,通常在代码中都不会直接 ...
- [转]android中drawable资源的解释及例子
原文链接: http://blog.csdn.net/wode_dream/article/details/38584693 文章中的内容参考Dev Guide中的Drawable R ...
- android 中targetSdkVersion和与target属性的区别
AndroidMenifest.xml中targetSdkVersion和project.properties中的target属性的区别 在AndroidMenifest.xml中,常常会有 ...
- Android 中pid与uid的作用与区别
PID:为Process Identifier, PID就是各进程的身份标识. 程序一运行系统就会自动分配给进程一个独一无二的PID.进程中止后PID被系统回收,可能会被继续分配给新运行的程序,但是在 ...
- ANDROID 中UID与PID的作用与区别
PID:为Process Identifier, PID就是各进程的身份标识,程序一运行系统就会自动分配给进程一个独一无二的PID.进程中止后PID被系统回收,可能会被继续分配给新运行的程序,但是在a ...
- [转] android 中 任务、进程和线程的区别
PS: handler的目的是在组件进程中开辟一个线程作为消息的poller,收到消息后可以更新Activity中的控件(特殊的view) 任务.进程和线程 关于Android中的组件和应用, ...
- Android中UID和PID的作用和区别
PID:为Process Identifier, PID就是各进程的身份标识,程序一运行系统就会自动分配给进程一个独一无二的PID.进程中止后PID被系统回收,可能会被继续分配给新运行的程序,但是在a ...
随机推荐
- js-day05-对象
为什么要学习对象 没有对象时,保存网站用户信息时不方便,很难区别 对象是什么 1.对象是一种数据类型 2.无序的数据集合 对象有什么特点 1.无序的数据的集合 2.可以详细的描述某个事物' 对象使用 ...
- 【Java EE】Day14 Servlet、HTTP、Request
一.Servlet 二.HTTP 三.Request 四.登录案例
- 【Java】【数据库】索引为何使查询变得更快?--B+树
排序数据的二分查找 二分查找的时间复杂度是\(O(log_2n)\),明显快于暴力搜索. 索引 建立索引的数据,就是通过事先排好顺序,在查找时可以应用二分查找来提高查询效率. 所以索引应该尽可能建立在 ...
- RequestMappingHandlerMapping请求地址映射的初始化流程!
之前的文章里,介绍了DispatcherSerlvet处理请求的流程. 其中一个核心的步骤是:请求地址映射,即根据request获取对应的HandlerExcecutionChain. 为了后续的请求 ...
- Pytorch 基本操作
Pytorch 基础操作 主要是在读深度学习入门之PyTorch这本书记的笔记.强烈推荐这本书 1. 常用类numpy操作 torch.Tensor(numpy_tensor) torch.from_ ...
- MySql索引下推知识分享
作者:刘邓忠 Mysql 是大家最常用的数据库,下面为大家带来 mysql 索引下推知识点的分享,以便巩固 mysql 基础知识,如有错误,还请各位大佬们指正. 1 什么是索引下推 索引下推 (Ind ...
- Mapper的动态代理
可以自动生产接口的实现类 ,所以就不需要再写daoImpl这个实现类了, 直接使用sqlSession.getMapper自动生成实现类 @Before 此注解的目的是为了将@Befoe 作为首先执行 ...
- Potree 002 Desktop开发环境搭建
1.工程创建 我们使用Visual Studio 2022开发,把下载好后的PotreeDesktop源码添加到Visual Studio中. 打开Visual Studio 2022,新建Asp.N ...
- 我的第一个自动刷作业脚本(大起大落的selenium经验分享)
起因 故事的开始是大二的上学期,有一门叫计算机结构(computer organization)的课.新教授这门课的教授在原来的政策上做了一些变动.他引入了一个叫做zybook的作业平台来确保我们能跟 ...
- python利用matplotlib生成迷宫
起因 我想要写一个项目叫python迷宫游戏,需求是玩家能和机器对抗率先走出迷宫,至少要有两个等级的电脑. 慢慢来,首先迷宫游戏需要有一个迷宫并展示出来,这便是这篇博客的目的 假设迷宫使用0表示点,1 ...



















