图片加载框架思考与理解

1,897 阅读4分钟

一、背景

  1. 工作中,最常使用的就是Glide,因此一直想了解它的内部机制。
  2. 好早之前看了Glide源码,陷进了源码细节无法自拔,笔记也记了一些比如:“Glide的with方法里,先是封装了RequestManager类,然后封装了xxx类………………”,这些没有意义的流程性的东西。
  3. 现在站在整体的角度,希望对Glide有一些有用的理解,也功利性的思考:了解它的原理能带给我哪些好处。

本文将主要介绍Glide,同时将其与其他常用的框架Picasso、Fresco相比较

二、图片加载框架

  • 首先,要明白Glide是一个图片加载框架;图片加载框架是有一个总体套路的,如图: *
    在这里插入图片描述
  • 也就是说,我们自己也可以通过这个流程实现一个图片框架。
  • 那么我们要了解的就是,Glide以及其他开源图片加载框架凭什么就能比我自己写的好?我自己写能不能写的比它好?

三、Glide

1、缓存

  1. 图片框架的一般套路是:三级缓存(内存->磁盘->网络)

为什么要三级缓存?答:原则上,不耗费流量的优先,访问速度快的优先。因此,内存既不耗费流量,速度又快,放在第一个获取;磁盘不耗费流量,速度一般,放在第二个;网络既耗费流量,速度又慢,放在最后不得已的时候才进行。

  1. 不服气:我自己也可以写一个三级缓存,那么我为什么要用Glide?它的缓存凭什么比我的好?至此就引出了Glide的缓存机制:

1.1、Glide的缓存机制

  • Glide是在三级缓存的基础上做了优化:
    1. 优化一(内存缓存的优化):弱引用缓存正在使用的图片+LruCache
      • 一开始有个疑问,弱引用缓存正在使用的图片,为什么不能用强引用缓存?有什么意义呢?
      • 答:如果没有弱引用缓存,那么LruCache有可能回收掉正在使用的图片(如果正在使用的图片很多,那么最早存进LruCache的图片为“最近最少使用资源”,会被回收);此时如果再此使用这张图片,会发现内存缓存找不到了,从而跳到磁盘缓存寻找。
      • LruCache达到设置的内存大小时,正在使用的图片在LruCache的缓存被回收,此时弱引用缓存存在,因此直接就可以拿来复用,而不用到磁盘缓存了。
    2. 优化二(磁盘缓存的优化--缓存ImageView大小的图片)
      • Glide相比于Picasso,后者会缓存原来大小的图片到内存,前者缓存ImageView大小的图片;
      • 因此会导致这些不同:
        • Picasso占用内存较大,加载图片较慢(每次加载都要把原图大小裁剪成ImageView大小)
        • Glide占用内存小,加载图片快(直接把缓存加载进ImageView即可);但是如果同一张图片加载到不同大小的ImageView,则会重新去网络请求、重新缓存一个新的大小的图片。
      • Glide支持设置DiskCacheStrategy.ALL缓存策略,既缓存ImageView大小的图片,又缓存原图,内存充足时,推荐使用!

2、Bitmap池

  1. UIL是一个老图片加载框架了,它基本可以实现一般的加载图片功能,但是它有一个很大的问题:在列表中快速滑动频繁加载图片时会卡顿
    • 这是因为快速滑动时,会频繁申请内存用来创建Bitmap对象,也会频繁的销毁Bitmap对象,因而会导致频繁的GC,就造成了内存抖动,阻塞主线程导致了卡顿。
  2. Glide如何解决的?
    • 答:Glide维护了一个Bitmap池来进行Bitmap对象的复用。

3、Bitmap格式

  1. Picasso默认使用ARGB_8888格式的Bitmap;Glide默认使用RGB_565格式的Bitmap。
  2. RGB_565ARGB_8888格式的占用内存小一半,以不支持透明度为代价,只造成了些许失真。
  3. 总结:如果不使用透明度,则推荐使用RGB_565;如果要使用透明度,而且对图片质量要求非常高,则可以用ARGB_8888

4、生命周期

  1. Glide通过with绑定了context的生命周期,如果传入的是Activity或者Fragment,就会在Activity或者Fragment销毁时,销毁页面中使用的图片以及正在进行的网络请求。
  2. 如果在某个Activity里,传入的是Application的context,那么就会在应用退出时,才销毁图片以及正在进行的网络请求。
  3. 因此,使用时推荐使用Activity或者Fragment的context!

5、Gif图

  1. Glide、Fresco支持Gif图、Picasso不支持

综上,Glide比Picasso强大

四、Fresco---最专业,黑科技!

优点(只介绍自己觉得牛逼的)

  1. 5.0以下将图片存到一块特别的内存中,自己进行管理(减少5.0以下手机OOM几率)
  2. 渐变加载图片:图片从模糊慢慢到清晰(Android系统并不支持,Fresco自己实现的,非常牛逼!)

缺点

  1. 使用比较复杂
  2. 需要使用DraweeView替代ImageView