课程名称:BAT大牛亲授技能+技巧 Android面试快速充电升级
课程章节:Android基础相关面试问题
主讲老师:DocMike
课程内容
1.recycle() 方法
在 Bitmap 中有一个 recycle() 方法,见名知意,用来回收 Bitmap 占用的内存空间。Bitmap 占用的内存空间包括 Java 占用的堆栈空间和 native 占用的内存空间。Java 有自己的垃圾回收机制,为什么 Bitmap 还要提供这样一个方法?
Android 有自己的回收机制,对于是否需要调用 Bitmap 的 recycle() 方法,还是需要看情况而定,如果只使用少量的几张图片,是否调用这方法影响不大。如果有大量的 Bitmap 需要垃圾回收处理,Java 的垃圾回收机制会频繁的调用 GC,引起内存的抖动,这时还是主动调用 recycle() 方法比较好。
2.Bitmap 中的 LRU
LRU(Least Recently Used)最近最少使用算法,在 Bitmap 中维护了一个 LinkedHashMap 队列。数据淘汰的原理是最近最少使用的数据,将会被淘汰,如果某条数据最近被访问过,那么之后的一段时间可能被访问的几率就会增加,优先级也会提高。如果某条数据很长时间没有被访问,优先级也会降低。当 LruCache 缓存的内存数据达到了设定的缓存大小之后,优先级低的数据会被优先淘汰。
在获取数据时,如果有缓存,即 LinkedHashMap 缓存中存在该 key 对应的数据, 那么直接返回该数据, 并且将该数据放到队头。如果没有缓存,即 LinkedHashMap 缓存中不存在该 key 对应的数据,那么需要创建该数据,并插入到 LinkedHashMap 中,并且返回该数据。
在插入数据处理时,如果缓存没有满,则向 LinkedHashMap 插入数据,直接将该数据插入到队头。如果缓存满了,将队尾的若干数据移除队列,然后将新数据插入到队头。
3.计算 inSampleSize
Bitmap 可以对图片按照一定的采样率进行缩放,主要是通过 BitmapFactory.Options 参数实现的。其中主要是 inSampleSize 参数,即采样率。通过对 inSampleSize 的设置,对图片的像素的高和宽进行缩放。
- 当 inSampleSize=1 时,即采样后的图片大小为原始大小;
- 当 inSamoleSize < 1,也按照1来计算;
- 若 inSampleSize > 1,即采样后的图片将缩小,缩小比例为1/(inSampleSize的二次方)。
官方文档给出的建议是,inSampleSize 的取值应该总是2的指数,如1,2,4,8等,如果外界传入的 inSampleSize 的孩子不为2的指数,那么系统会向下取整并选择一个最接近2的指数代替。
4.缩略图
如果用 ImageView 来显示 Bitmap,一般情况下 ImageView 的宽高会小于 Bitmap,如果将一个完整的 Bitmap加载到偏小的 ImageView 中会浪费内存。关于这个问题,Android官方提供了一个优化方法 calculateInSampleSize(),该方法通过比较 ImageView 与 Bitmap 的大小并计算采样率,最终将采样后的小图加载到内存中。
具体过程是在调用 BitmapFactory.decodeXXX() 方法解析图片时,先将 BitmapFactory.Options 的inJustDecodeBounds 设为 true,此时不会将图片加载到内存中,而是只得到 Bitmap 的宽高,随后通过图片宽高计算采样率。得到采样率后再将 inJustDecodeBounds 设为 false,再加载 Bitmap 时可以得到大图的采样图。
5.三级缓存
三级缓存说的是内存缓存、本地磁盘缓存和网络缓存。三级缓存的原理就是当 App 需要引用缓存时,首先到内存缓存中读取,读取不到再到本地缓存中读取,还获取不到就到网络异步读取,读取成功之后再保存到内存和本地缓存中。
对于图片的缓存可以创建自己的工具类,因内存缓存中取速度较快,所以先从内存缓存中取,如果内存取不到其次从本地缓存中取,如果本次缓存取不到最后从网络缓存中取。
内存缓存可以使用 LruCache。LruCache 可以用来存储各种类型的数据,可以设置大小。本地缓存可以根据路径获取本地文件,为了安全可以对路径进行加密,作为文件名。从网络中下载图片时,需要考虑异步问题。
课程收获
这一节内容对 Bitmap 面试中可能会问到的问题,进行了整理和总结。对于 App 开发来说,Bitmap 的使用必不可少,我们不仅要会使用,还要了解这背后的设计思想。
共同学习,写下你的评论
评论加载中...
作者其他优质文章