美文网首页
性能优化<第七篇>:图片缓存优化

性能优化<第七篇>:图片缓存优化

作者: NoBugException | 来源:发表于2021-06-23 23:43 被阅读0次

图片解码之后生成Bitmap,Bitmap对象占用的内存特别大,这种情况特别容易造成内存抖动,甚至发生OOM。解决这个问题除了图片压缩之外,还需要合理的控制图片的缓存。
缓存有三级,分别是:网络、磁盘、内存,即三级缓存。

(1)三级缓存
1、定义

网络缓存:从网络读取图片,ImageView可以将网络图片直接显示出来;
磁盘缓存:从本地读取图片,ImageView可以将本地图片直接显示出来;
内存缓存:如果Bitmap存在内存中,ImageView可以直接将Bitmap显示出来;

2、加工

如果直接将网络图片显示在屏幕上,很容易发生OOM,因为网络图片的大小不可控制,谁也不知道网络图片的大小是多少。
所以,首先需要将图片下载到本地并压缩,然后将压缩后的图片解码成Bitmap。

3、策略

先从内存中获取图片,如果没有就从磁盘中取,如果磁盘中依然没有,会从网络中获取。
(2)一些概念
1、软引用和弱引用

为了方便回收Bitmap对象,最好将Bitmap对象用软引用或者弱引用修饰;
软引用:当内存不够的时候才会被GC回收;
弱引用:当GC执行的时候立即被回收;

根据软弱引用的特性,推荐使用`弱引用`。

2、回收

Bitmap对象可以使用以下方法回收:

    bitmap.recycle()

然而,这个方法特别容易造成如下异常:
image.png
顾名思义,已经被回收的Bitmap对象再次被使用了。所以,使用该方法要非常谨慎。

3、复用

Bitmap所属的内存块是可以复用的,`BitmapFactory.Options`的`inBitmap`属性可以存储Bitmap对象,
当`BitmapFactory.Options`的`inMutable`属性为true时,则支持复用,所以`inMutable`和`inBitmap`会一起使用。
完成的代码如下:

            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inMutable = true;
            bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.kongque, options);
            options.inBitmap = bitmap;
            bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ceshi, options);

`inMutable `的赋值必须在`decodeXXX`之前,生成Bitmap之后,将Bitmap赋值给`inBitmap`。

4、内存缓存(LruCache)

LruCache是Android自带的内存缓存类,`LruCache`采用最近最少使用算法,将最近最少使用的缓存清除。
(3)手写四级缓存架构(简化版)

平时我们所说的三级缓存是指:内存缓存 + 磁盘缓存 + 网络缓存。

四级缓存就是:内存缓存 + 复用池 + 磁盘缓存 + 网络缓存。

为此,我手写了一个简单的加载网络图片的框架。

地址是:https://github.com/NoBugException/ImageCache

注意:
Demo只适用于学习和总结,如果用在项目中使用并不能保证稳定,因为Demo并没有经过精细的测试过。

相关文章

网友评论

      本文标题:性能优化<第七篇>:图片缓存优化

      本文链接:https://www.haomeiwen.com/subject/qoevlltx.html