亦余心之所善兮,虽九死其犹未悔。这篇文章主要讲述Android高效内存之让你的图片省内存相关的知识,希望能为你提供帮助。
android高效内存之让你的图片省内存
在做内存优化的时候,我们发现除了解决内存泄露问题,剩下的就只有想办法减少真实的内存占用。而在App中,大部分内存可能被我们图片占用了,所以减少图片的内存占用可以带来直接的效果。
一、一张图片到底占用多少内存我们先假设我们有一张图片是600 * 800像素的,图片磁盘占用空间大小假设是 100KB。
图片内存大小跟磁盘占用空间大小有什么关系?
磁盘占用空间的大小不是图片占用内存的大小,磁盘占用空间是在磁盘上存储图片需要的一个空间大小,内存大小是加载到内存中占用的内存大小。两个只是单位是一样的,本质不是一个概念。
一张图片到底占用多少内存呢?
图片占用内存的计算公式是:图片高度 * 图片宽度 * 一个像素占用的内存大小,在Android中一般情况下默认一个像素占用内存是4个字节,所以上面的图片占用内存是:800 * 600 * 4 byte = 1875KB = 1.83M。为什么是4个字节呢?一定是4个字节么?这两个问题后面仔细讲。
图片所在目录对内存的影响?
在Android中,图片的存放目录和手机的屏幕密度影响图片最终加载到内存的实际大小,举个例子:假设我们的图片放到xhdpi目录下,那么我们本文中的图片占用的内存大小如下.
- 屏幕密度为2的设备:800 * 600 * 4byte = 1.83M
- 屏幕密度为3的设备:800 * 1.5 * 600 * 1.5 * 4byte = 1.83 * 2.25M = 4.12M
- 这里所说的屏幕密度是指android.util.DisplayMetrics类中的density变量,是一个float值,关于屏幕密度的更多内容本文不做介绍。
文章图片
【Android高效内存之让你的图片省内存】所以,计算图片占用内存大小的时候,要考虑图片所在的目录跟屏幕密度,这两个因素其实影响的是图片的高宽,Android会对图片进行拉升跟压缩。
二、 让你的图片省内存 2.1 让你的图片最小化
图片的内存占用计算方式为:图片高度 * 图片宽度 * 一个像素占用的内存大小,所以图片的高宽如果都变为原来宽高的2倍,那么内存将变为原来的4倍。所以图片的使用原则可以总结如下:
- 使用尽可能小的图
- 使用.9图,.9图本身也要尽可能的小
- 自己绘制(覆写View的onDraw自己画)或者使用Drawable来绘制
文章图片
2.2 在内存中压缩图片
加载大图片时需要对图片进行压缩,使用等比例压缩方法直接在内存中处理图片。
Options options = new BitmapFactory.Options(); options.inSampleSize = 5; // 原图的五分之一,设置为2则为二分之一 Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
这样做要注意的是,图片质量会变差,inSampleSize设置的值越大,图片质量就越差。
2.3 读取位图尺寸和类型时不把图片加载到内存中
有时候我们取得一张图片,也许只是为了获得这个图片的一些信息,比如图片的width、height等信息,不需要显示到界面上,这个时候我们可以不把图片加载到内存中。
BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(getResources(), R.id.myimage, options); int imageHeight = options.outHeight; int imageWidth = options.outWidth; String imageType = options.outMimeType;
2.4 用完就回收
由于Android外层是使用java,而底层使用的是C语言为图片对象分配的内存空间。所以我们的外部虽然看起来释放了,但里层却并不一定完全释放了,我们使用完图片后最好再释放掉里层的内存空间。
if (!bitmapObject.isRecyled()) {// Bitmap对象没有被回收 bitmapObject.recycle(); // 释放 System.gc(); // 提醒系统及时回收 }
2.5 降低要显示的图片色彩质量
2.5.1 颜色模型RGB(ARGB)
RGB色彩模式是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。在Android中还有包含透明度Alpha的颜色模型,即ARGB。
文章图片
2.5.2 RGB在计算机中颜色值的数字化编码在不考虑透明度的情况下,一个像素点的颜色值在计算机中的表示方法有以下3种:
- 浮点数编码:比如float: (1.0, 0.5, 0.75),每个颜色分量各占1个float字段,其中1.0表示该分量的值为全红或全绿或全蓝。
- 24位的整数编码:比如24-bit:(255, 128, 196),每个颜色分量各占8位,取值范围0-255,其中255表示该分量的值为全红或全绿或全蓝。
- 16位的整数编码:比如16-bit:(31, 45, 31),第1和第3个颜色分量各占5位,取值范围0-31,第2个颜色分量占6位,取值范围0-63。
2.5.3 Android中RGB编码格式(整型编码)
- RGB888(int):R、G、B分量各占8位
- RGB565(short):R、G、B分量分别占5、6、5位
- RGB555(short):RGB分量都用5位表示(剩下的1位不用)
- ARGB8888(int):A、R、G、B分量各占8位
- ARGB4444(short):A、R、G、B分量各占4位
文章图片
在Android中系统默认使用的编码格式是ARGB_8888,所以在文章开头计算图片内存大小的时候每个像素占用内存大小是4byte,比如采用ARGB_8888编码载入一张1920*1200的图片,大概就会占用1920*1200*4/1024/1024=8.79MB的内存。
2.5.4 降低要显示的图片色彩质量采用低内存占用量的编码方式,比如Bitmap.Config.ARGB_4444比Bitmap.Config.ARGB_8888更省内存,比如1920*1200的图片。
- ARGB_8888:1920*1200*4/1024/1024=8.79MB
- ARGB_4444,RGB565:1920*1200*2/1024/1024=4.39MB
推荐阅读
- Android各种模拟器使用笔记
- 解决android studio上“com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65935”问题(
- Android问题-“signaturs do not match the previously installed version”
- WebRTC之Android客户端
- Android实例-红外线操作(XE10.2+小米5)
- Android Studio 快速开发
- 如何在MacOS上安装WordPress
- 如何在MacOS上安装VLC
- 如何在MacOS上安装Sublime Text