文章插图
一、由来
在我们编写 Android 程序的时候,几乎永远逃避不了图片压缩的难题 。除了应用图标之外,我们所要显示的图片基本上只有两个来源:
- 来自网络下载
- 本地相册中加载
文章插图
OOM 即 OutOfMemory 异常,也就是我们所说的 内存溢出,其一般表现为应用闪退等现象 。那么我们该如何下手去解决呢?
文章插图
二、解决方案首先我们发现,我们所加载的这些图片的分辨率,要比我们手机屏幕高得多,更有甚者,我们在一个拇指大的控件上,去加载一个 4k 大图是完全没有必要的,也就是说,如果我们能让每个控件上都去显示相应大小的图片,那么这个问题也就迎刃而解了
那么,要怎样才能达到图片与控件的对号入座?这时我们就引进了图片压缩的方案:
- 首先,获得原图片大小
- 其次,获取控件大小
- 接着,获取我们图片和控件的比例
- 最后,根据这一比例,将图片压缩为适合显示的大小
三、获取原图大小我们都知道,Android 向我们提供了 BitmapFactory 这个类,在这个类中有着诸如:decodeResource() decodeFile() decodeStream() 等:
文章插图
其中:
- decodeResource() : 用于解析资源文件,即 res 文件夹下的图片
- decodeFile() : 用于解析系统相册中的图片
- decodeStream() : 用于解析输入输出流中图片通常,是采用 HttpClient 从下载的图片
虽然这些方法对我们是再熟悉不过的了,但对于某些初学者而言,却经常忽略了一个重要的内部类 :BitmapFactory.Options,然而他确实我们图片压缩必不可少的,为什么需要这个参数呢?Options 的对象用于确定需要生成的 Bitmap 即目标图片的参数 。
他的用法很简单,我们先 new 一个 BitmapFactory.Options 对象 。再去调用含有 Options参数的方法,如
- public static Bitmap decodeResource(Resources res, int id, Options opts)
- public static Bitmap decodeResourceStream(@Nullable Resources res,@Nullable TypedValue value,@Nullable InputStream is, @Nullable Rect pad, @Nullable Options opts)
为什么会发生这种情况?首先我们想想我们为什么要获得这个Options 对象?时为了获得图片的尺寸大小;那我们为什么要获得原图尺寸大小?是为了按照原图尺寸和控件尺寸的比例,将其压缩为适合显示的大小?那我们又为什么要去压缩它为合适的大小呢?是因为如果按照原大小去调用相应的 decode...()方法解析图片,会导致内存占有率过高触发OOM 异常,进而导致程序崩溃啊!没想到的是:结果我们为了获得 Options 而调用了相应的 decode...() 方法,的确 Options 是复制了,但由于该方法适用于生成图片,也就是 Bitmap 对象的 。所以程序也在解析这张超大图的过程中OOM 崩溃了
文章插图
【Android 图片压缩策略详解,有效解决 Android 程序 OOM】
那么难道就没方法了吗?
有的,我之前说过:Option 内部有着众多参数,其中有一个叫做: inJustDecodeBounds。这个参数默认值为false。但如果我们先把这个参数设置为 true 时,该方法便不在会去生成相应的 Bitmap,而仅仅是去测量图片的各种属性,如长度、宽度、类型等等,然后放回一个 null。所以,我们很容易想到:可以先通过将 inJustDecodeBounds 的值设为 true,再去调用相应的相应的 decode...()方法,最后再将inJustDecodeBounds 的值改回 false 。这种做法有两个好处:
推荐阅读
- 祁门红茶价格表及图片
- 滇红茶鉴别图片
- 滇红茶种类名称图片大全
- 滇红茶种类名称图片
- 梦见弖优芽美图片 狂赌之渊梦见弖优芽美
- 正宗祁门红茶图片
- 人和猪的照片 人面对猪图片
- 小种红茶种类图片
- 宜兴红茶品之味的价格和图片
- 宜兴红茶原生态价格和图片