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 ...
随机推荐
- SpringMVC01:入门、请求参数绑定、自定义类型转换器、常见注解
一.介绍--三层架构和MVC 1.三层架构介绍和MVC设计模型介绍 开发架构一般都是基于两种形式,一种是 C/S 架构,也就是客户端/服务器,另一种是 B/S 架构,也就是浏览器/服务器.在 Java ...
- 【Hive】概念、安装、数据类型、DDL、DML操作、查询操作、函数、压缩存储、分区分桶、实战Top-N、调优(fetch抓取)、执行计划
一.概念 1.介绍 基于Hadoop的数据仓库工具,将结构化数据映射为一张表,可以通过类SQL方式查询 本质:将HQL转换成MapReduce程序 Hive中具有HQL对应的MapReduce模板 存 ...
- ubuntu1804搭建FTP服务器的方法
搭建FTP服务器 FTP的工作原理: FTP:File Transfer Protocol ,文件传输协议.属于NAS存储的一种协议,基于CS结构. ftp采用的是双端口模式,分为命令端口和数据端口, ...
- input、print、字符串格式化输出
1.使用input(), print()进行用户交互 """ 以前银行取钱只能拿着存折去柜台跟小姐姐交流才可以 你想干嘛 我想取钱 请输入密码 滴滴滴密码 想取多少钱 我 ...
- Go适合做什么?为何这么多人偏爱Go语言?
Go作为Google2009年推出的语言,其被设计成一门应用于搭载 Web 服务器,存储集群或类似用途的巨型中央服务器的系统编程语言. 对于高性能分布式系统领域而言,Go 语言无疑比大多数其它语言有着 ...
- day02-功能实现01
家具网购项目实现01 1.项目开发环境搭建 创建一个web项目,添加需要的jar包(暂不使用Maven) 依照5.1的表格来创建项目的大体分层: 2.功能01-搭建前端页面 2.1需求分析/图解 2. ...
- 【RocketMQ】主从模式下的消费进度管理
在[RocketMQ]消息的拉取一文中可知,消费者在启动的时候,会创建消息拉取API对象PullAPIWrapper,调用pullKernelImpl方法向Broker发送拉取消息的请求,那么在主从模 ...
- java中加号的用法
注意java中+号的使用 public class Add { public static void main(String[] args) { System.out.println(100+80); ...
- SQL 之 SELECT语句
1.展示所有列语法 select * from table; #table表示表名 示例: select * from a 2.展示指定列语法 select column1, column2, ... ...
- Transition 初步使用
Transition Vue 提供了 transition 的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡: 条件渲染 (使用 v-if) 条件展示 (使用 v-show) 动态组件 ...



















