从事过移动端应用开发的童鞋应该都清楚,内存是非常宝贵的资源。如果能很好的利用有限的内存,对应用性能的提升会有很大的帮助。在实际应用开发中图片内存占整个应用非常大的比重,我们只有了解图片是如何加载到内存中,才能更好的优化图片所占的内存。

那么对于图片在Android应用中的使用进行探讨一下。

图片所占内存大小=内存中图片高 * 内存中图片宽 * 每个像素所占字节数  

1,那么图片的物理高宽和加载到内存中的高宽是否是一样的呢?

在应用中关于图片的加载一般分为两种情况,其加载到内存中的大小也是不一样的:

第一种,图片资源放在drawable或mipmap中,通过R.drawable.*或者R.mipmap.*的方式读取。这类多半是应用的切图文件等;

第二中,非通过R文件获取的图片资源。例如存放在sd文件中或者网络中等;

对于第一种情况,是由系统通过当前设备的density来选择读取对于density目录下的图片资源,资源的匹配是由对应的density目录开始检索,如果对应目录没有则到比当前density小的目录中寻找,只到找到图片为止。

属性名 ldpi mdpi hdpi xhdpi xxhdpi xxxhdpi
目录对应DPI 120 160 240 320 480 640

这类加载方式图片在内存中的大小计算公式如下:

内存中长度 =( 图片真实长度  /  图片所在目录DPI) * 设备DPI

                        例如:图片的真实高度是192px,图片资源放在xhdpi目录中,测试的设备DPI=560 那么加载到内存中的高度=  (192 / 320) * 480 =288

对应第二种情况,是由开发者直接指定图片资源的地址,系统不会对图片进行处理:

内存中长度= 图片真实长度

                     

    2,像素所占字节数是如何计算的呢?

关于这个问题官网中给了很明确的解释,是通过Bitmap.Config来决定的

android系统中默认的bitmap.Config是 Bitmap.Config.ARGB_8888 所以每个像素占4个字节

那我们来验证下上面所说的是否正确:在hdpi,xhdpi,xxhdpi,xxxhdpi已经sdcard中使用同一张图片大小为192px*192px.

测试的设备为:1080*1920 density=3.0 DPI=480

          

          由上图可以看到,不同的目录图片所对应的内存大小

           sdcard:  高宽=  192px                                            内存=192*192*4 = 144kb

hdpi :         高宽 = (192 /240 )*480=384px                            384*384*4=576kb

xhdpi:        高宽 = (192/320)*480=288px                           288*288*4=324kb

xxhdpi:       高宽 = (192/480)*480 = 192px                         192*192*4=144kb

xxxhdpi:      高宽 = (192/640)*480 = 144px                          144*144*4=81kb

为了验证在实际运行中图片所在内存是否符合我们的计算公式,我们可以利用AS的监控功能dump出运行时的dump文件进行分析验证。

通过验证可以得知图片所占的内存大小符合前面的公式:192*192*4=147456B

最后对在应用中使用图片的有些建议:

1,切图资源不能随便乱放文件夹,最好按照对应的切图放到对应的文件家中,避免因为访问其他文件加导致图片所占内存增大。

2,对于只有一套切图资源来说,尽量选择高精度的尺寸切图。参考当前主流设备的设备信息选择对应的精度作为切图标准。目前我以xxhdpi作为切图标准

3,对应非同R文件引用的图片,可以选择设置Bitmap.Config属性控制图片内存大小,可以选择Bitmap.Config.RGB_565的方式,相比默认的Bitmap.Config.ARGB_8888将会减少一半的内存占用

示例代码

关于Android应用中图片占用内存浅谈的更多相关文章

  1. Android中图片占用内存的计算

    Android中图片占用内存的计算 原文链接 http://blog.sina.com.cn/s/blog_4e60b09d01016133.html   在Android开发中,我现在发现很多人还不 ...

  2. (转)Android中图片占用内存计算

    在Android开发中,我现在发现很多人还不会对图片占用内存进行很好的计算.因此撰写该博文来做介绍,期望达到抛砖引玉的作用.   Android中一张图片(BitMap)占用的内存主要和以下几个因数有 ...

  3. android上的图片占用内存问题

    近日正在把ios程序移植到android上,以前没做过android的程序,于是,想当然地把ios的图片资源放到了android工程的drawable文件夹下,这些图片都是png. 程序界面也很正常. ...

  4. android 图片占用内存与什么有关

    android 图片占用内存与什么有关 原文链接:http://blog.csdn.net/zjl5211314/article/details/7041813 在开发手机应用的时候,内存是有限的,那 ...

  5. 图片--Android加载图片导致内存溢出(Out of Memory异常)

    Android在加载大背景图或者大量图片时,经常导致内存溢出(Out of Memory  Error),本文根据我处理这些问题的经历及其它开发者的经验,整理解决方案如下(部分代码及文字出处无法考证) ...

  6. Android加载图片导致内存溢出(Out of Memory异常)

    Android在加载大背景图或者大量图片时,经常导致内存溢出(Out of Memory  Error),本文根据我处理这些问题的经历及其它开发者的经验,整理解决方案如下(部分代码及文字出处无法考证) ...

  7. Android ADT中增大AVD内存后无法启动:emulator failed to allocate memory 8 (转)

    Android ADT中增大AVD内存后无法启动:emulator failed to allocate memory 8http://www.crifan.com/android_emulator_ ...

  8. 【已解决】Android ADT中增大AVD内存后无法启动:emulator failed to allocate memory 8

    [问题] 折腾: [已解决]Android ADT中增大AVD内存后无法启动:emulator failed to allocate memory 8 过程中,增大对应AVD的内存为2G后,结果无法启 ...

  9. 【已解决】Android ADT中增大AVD内存后无法启动:emulator failed to allocate memory

    [已解决]Android ADT中增大AVD内存后无法启动:emulator failed to allocate memory 结论是: 当前有个bug: 默认是通过 hw.ramSize=1024 ...

随机推荐

  1. innobackupex基于binlog日志的恢复 -- 使用mysqlbinlog恢复

    备份先做一次完整备份: innobackupex --defaults-file=/etc/my.cnf --user root --password chengce243 /data/mysqlba ...

  2. theano 模块 MLP示例

    theano 模块 MLP示例,有需要的朋友可以参考下. theano教程Example: MLP: 约定数组为列向量, 层级:将多层传感器定义为一连串的层级,每个层级定义为一个类.类属性包括:权重. ...

  3. 阿里云服务器下安装LAMP环境(CentOS Linux 6.3) 安装与配置 FTP 服务器

    我们经常会使用 FTP,把本地电脑上的文件上传到服务器上,或者把服务器上的文件下载到自己的电脑里面.FTP 有服务端和客户端,FTP 的服务端提供了这种传输文件的服务,FTP 的客户端提供了传输文件的 ...

  4. 2013.10.26工作Fighting(1)

    1.今天虽然花费了六个小时来解决一个功能,最后用一行代码来搞定了. ----遇到问题,解决的办法总是比问题多. 2.给你分配有难度的任务,应该是激动.这样才能挑战自我,学得到很多兴奋的新东西. --- ...

  5. mysql查看版本,编码

    SELECT * FROM gps_gpsinfo t WHERE t.reportdate < TO_DATE('2019/4/28 10:05:07', 'yyyy-MM-dd hh24:m ...

  6. js基础之语言部分必须要掌握的五大方阵

    javascript基础部分可以从"数组, 函数, 作用域, 对象, 标准库"这5大方阵进行学习: (一).数组 数组的声明(2种):; a,自变量声明 var a = ['a', ...

  7. 安装配置eclipse的图文步骤

    装eclipse 之前要确定自己是否已经安装了java开发环境JDK,JDK的版本64位要下载Eclipse版本64位:JDK32位,要下载Eclipse32位. 一.去eclipse官网下载ecli ...

  8. shell脚本中case的用法

    shell脚本中case选择语句可以结合read指令实现比较好的交互应答操作,case接收到read指令传入的一个或多个参数,然后case根据参数做选择操作. case的语法如下 case $char ...

  9. c++运算符重载和虚函数

    运算符重载与虚函数 单目运算符 接下来都以AClass作为一个类例子介绍 AClass{ int var } 区分后置++与前置++ AClass operator ++ () ++前置 一般设计为返 ...

  10. shell 流水账

    在shell脚本运行时,会先查找系统环境变量ENV,该变量指定了环境文件(加载顺序通常是/etc/profile ~/.bash_profile ~/.bashrc /etc/bashrc) 设置全局 ...