内存占用用手就能算出来
当我们看完本篇文章,你应该可以知道:
- 占用的内存,不是说的图片的文件大小
- 我们可以在运行时去获取
- 要掌握图片内存大小的计算方法
一、如何在运行时获取Bitmap的大小?
- 获取图片实际需要的内存大小
public final int getByteCount() {if(mRecycled) {return 0;}return getRowBytes() * getHeight();}
- 图片实际占用的内存大小
因为存在一个复用的场景,比如之前已经开辟了400KB的大小用来显示图片A,现在我们需要显示300KB的图片B,而且图片A已经不需要显示了,那么可能就会将之前开辟的400KB用来显示图片B,这样就不需要重新开辟新的内存,所以图片B实际占用的内存400KB。
public final int getAllocationByteCount() {if(mRecycled) {return 0;}return nativeGetAllocationByteCount(mNativePtr);}
二、图片的来源
- Assets中的图片
asstes中的文件基本等同于我们从SDCard中加载的图片,所以就不再单独讲解了。
举个例子:我们以宽高为112px * 131px像素的png图片为例(文件大小为20kb),如果我们使用下面的方式加载到内存中:
BitmapFactory.decodeStream(assets.open("test.png"));
实际上展示的是:以ARGB_8888的格式加载到内存中,那么最终的大小是112*131*4 = 58688KB。实际上就是我们图片需要显示的总的像素点数乘以单个像素点所占用的内存,因为ARGB_8888,可以看出来一个像素的四个通道分别需要8位来描述,所以一个像素点需要4个字节的内存,所以总的像素点数乘以4就是这张图所占用的总内存了。
所以,意味着图片的内存大小除了像素大小外,还和加载到内存的格式有关,比如我们将上面的图片换成RGB_565去加载,那么我们得出的内存就应该是:112*131*[(5_6+5)/8] = 112*131*2 = 29344个字节,足足比之前小了一半的大小。
- Drawable目录中的图片
当我们将图片放到不同的drawable目录中,最后显示出来占用的实际像素是有一定的缩放关系的,还是以112*131px的图片为例:
这么说吧,如果将上面的图片放到hdpi目录下,然后以ARGB_8888加载到内存中占用的内存大小算法就如下:
(112÷1.5)×(131÷1.5)× 3 × 4 = 77256字节
注意如果放在-nodpi中,那么图片在不同DPI的设备中不会做任何缩放,都只会以112×131的像素显示,所以在不同手机中永远占用相同的内存。
三、优化图片占用的内存体积
- 使用inSampleSize对图片进行采样、压缩
- 使用矩阵变化来改变图片大小
- 使用RGB_565来加载非透明图片
- 使用 9-patch图片来做背景图
- 使用VectorDrawable
- 能不用图片就不用图片
- 感兴趣的同学可以看下在Android8.1之前可以使用的索引模式(IndexedColor)
- NET跨平台:在Ubuntu下搭建ASP.NET 5开发环境
- 【Code】关关的刷题日记22——Leetcode 53. Maximum Subarray
- 【Java学习笔记之三十四】超详解Java多线程基础
- Codeforces 842B Gleb And Pizza【几何,水】
- Python3希尔排序
- Codeforces 842A Kirill And The Game【暴力,水】
- Wannafly模拟赛 A.矩阵(二分答案+hash)
- 【Java数据结构学习笔记之一】线性表的存储结构及其代码实现
- Comparison of Apache Stream Processing Frameworks: Part 1
- 【LeetCode】关关的刷题日记23——Leetcode 66. Plus One
- Codeforces Round #434 (Div. 2, based on Technocup 2018 Elimination Round 1)&&Codeforces 861A k-roun
- 【Java数据结构学习笔记之二】Java数据结构与算法之栈(Stack)实现
- 【Java数据结构学习笔记之三】Java数据结构与算法之队列(Queue)实现
- Comparison of Apache Stream Processing Frameworks: Part 2
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法