admin管理员组

文章数量:1597417

(一)图片

1、图片库对比

        (1)Universal ImageLoader是很早开源的图片缓存,在早期被很多应用使用

        优点:

  • 支持下载进度监听
  • 可以在 View 滚动中暂停图片加载
  • 默认实现多种内存缓存算法
  • 支持本地缓存文件名规则定义

        缺点:不支持GIF图片加载,缓存机制没有和Http的缓存很好的结合,完全是自己的一套缓存机制

        (2)Picasso是Square开源的项目,且他的主导者是JakeWharton,所以广为人知

        优点:

  • 自带统计监控功能
  • 支持优先级处理
  • 支持延迟到图片尺寸计算完成加载
  • 支持飞行模式、并发线程数根据网络类型而变
  •  “无”本地缓存

        缺点:于不支持GIF,并且它可能是想让服务器去处理图片的缩放,它缓存的图片是未缩放的,并且默认使用ARGB_8888格式缓存图片,缓存体积大

        (3)Glide是Google员工的开源项目

        优点:

  • 图片缓存->媒体缓存
  • 支持优先级处理
  • 与Activity/Fragment生命周期一致,支持trimMemory
  • 支持okhttp、Volley
  • 内存友好

        (4)Fresco是Facebook的开源的图片缓存

        优点:

  • 图片存储在安卓系统的匿名共享内存, 而不是虚拟机的堆内存中,图片的中间缓冲数据也存放在本地堆内存,所以,应用程序有更多的内存使用,不会因为图片加载而导致oom,同时也减少垃圾回收器频繁调用回收Bitmap导致的界面卡顿,性能更高

  • 渐进式加载JPEG图片,支持图片从模糊到清晰加载

  • 图片可以以任意的中心点显示在ImageView,而不仅仅是图片的中心

  • JPEG图片改变大小也是在native进行的,不是在虚拟机的堆内存,同样减少OOM

  • 很好的支持GIF图片的显示

        缺点:

  • 框架较大, 影响Apk体积
  • 使用较繁琐

2、图片库的源码分析

        Picasso源码分析

        (1)构造Picasso实例对象

        Picasso实例对象不是通过默认的构造器来构建的,而是通过内部类Bulider方式来构建的,这样可以方便用户自定义构建Picasso对象,默认方法是通过with来创建

        Builder可以组装构建Picasso的各种参数,例如定义内存缓存的大小

        (2)利用load方法加载图片

        Picasso支持多种加载图片的方式,例如根据网络Uri来加载图片,或者是加载ResourceId指定的图片等,所以load方法被重载了,有多种实现方式

        load方法最终都是返回一个RequestCreator,RequestCreator保存请求的参数

        (3)into方法将ImageView传入

        ImageView是通过into方法传入的,该方法在RequestCreator中实现

        RequestCretor是将Request封装成Action,然后提交请求到任务队列中,让任务异步执行。在构造请求之前,先从内存缓存中查看是否意见有图片了,如果有的话,则直接返回缓存中的图片,并回调callback接口

        (4)提交任务

        RequestCreator封装好任务请求后,将请求提交到任务队列中,请求入队列的过程在Picasso类中实现

        取消图片加载:

        (1)Dispatcher发送取消消息

        (2)延迟请求的取消

        当尝试调整图片的大小适应ImageView的边界,这将延迟执行该请求直至ImageView布局好了。具体在RequestCreator的fit方法中实现

        Glide源码分析

        (1)with()方法

        with()方法有很多的重载,传入的参数分别是Context、Activity、FragmentActivity、Fragment

        with()方法返回一个RequestManager对象,该对象是请求管理的对象,是通过RequestManagerRetriever的get()方法获取的,RequestManagerRetriever就是用来生产RequestManager对象的

        get()如果在主线程中执行,则使用当前页面的Context,否则使用ApplicationContext

        Glide没法直接监听Activity的生命周期,会在RequestManagerRetriever的fragmentGet()中创建一个没有UI的Fragment,通过它来间接的监听对应的生命周期

        (2)load()方法

        load()方法根据数据的来源不同有很多的重载

        load()中通过asDrawable()方法创建一个RequestBuilder实例,然后调用该实例的load()方法,该方法最终会调用loadGeneric()方法给RequestBuilder的成员变量赋值

        (3)into()方法

        在配置好imageUrl和一些参数设置之后调用into()方法显示图片

        into()方法必须要主线程中调用,否则抛出异常。在该方法中将传入的ImageView对象封装成了Target对象,创建Target实例以后就会调用参数为该实例的into()方法执行请求

3、图片框架缓存实现

        Universal ImageLoader,Picasso和Glide采用三级缓存策略,即内存缓存,本地缓存和网络缓存

        App优先访问内存中的图片缓存。若内存中没有,则查找本地缓存的图片,并将图片存储到内存中。若本地缓存中没有,则通过网络获取图片资源,将图片存储到本地缓存中

        Fresco采用四级缓存策略,即两级内存缓存,本地缓存和网络缓存

        App优先访问已解码内存缓存(Bitmap缓存)。若已解码内存缓存中没有,则查找未解码图片的内存缓存,将图片进行解码后,存储到已解码内存缓存中。若未解码图片的内存缓存中没有,则查找本地未解码的图片缓存,将解码后的图片存储到已解码内存缓存,将未解码的图片存储到未解码图片

本文标签: 面试题高级技术android