zoukankan      html  css  js  c++  java
  • 源码分析: 图片加载框架Picasso源码分析

    使用:

    Picasso.with(this)
    .load("http://imgstore.cdn.sogou.com/app/a/100540002/467502.jpg")
    .into((ImageView) findViewById(R.id.ivImage));

    (1),首先进入Picasso.with(this):

    创建一个Picasso类型单例singleton, 接着进入Builder构造函数:

    这里是通过传入的context获取全局的context,主要是为了防止内存泄漏, 接着我们看build方法:

    先简要分析一下这里的主流程,后面再进行详细分析:

    首先创建一个Downloader,看名字猜测应该是用于下载图片的; 接着创建一个LruCache用于图片的内存缓存; 然后创建一个ExecutorService子类PicassoExecutorService的线程池对象,用于执行具体的下载图片任务; 然后再创建一个请求转换器RequestTransformer对象(具体干嘛的目前还不知道,看名字猜测是做一些什么装换); 接着创建一个Stats对象(具体干嘛的目前还不知道,看名字猜测和状态有关); 然后再创建一个分发器Dispatcher对象,用于分发多个图片的请求到线程池里的线程去执行;
    最后,创建了一个Picasso对象返回.
    (2)进入load函数:


    首先判断图片路径是否为null,是的话则创建一个uri为null的请求生成器RequestCreator(应该是用来生成图片加载请求的);如果非null但url长度为0,则直接抛出异常;否则进入load的重载方法:

    根据图片路径path解析出相应的uri构建一个RequestCreator对象返回.

    (3)接下来看into方法,最终会调用into(ImageView target, Callback callback)方法:

    首先通过checkMain方法检查是否在主线程调用,不是在主线程则直接抛出异常(代码略),然后判断imageView是否为空,为空则抛出异常.
    
    

     这段代码是判断是否要延期处理,我们没有延期,直接跳过.

    这里首先根据开始时间创建一个请求,根据请求创建一个请求的key;
    然后根据内存缓存策略判断是否需要从内存中读取缓存图片,默认需要;
    如果需要从内存读取,则从内存读取图片,读取出来的图片如果非空,则返回,不用发起网络请求了;
    如果回调接口非空,则回调成功(我们这里是null,不管).

    先判断是否设置了占位图片,如果设置了则先显示占位图;
    接着创建一个Action对象,然后将这个action对象加入队列并提交到线程池执行.

    接着我们看看enqueueAndSubmit方法具体干了啥:

    首先获取上一步创建Action时设置的ImageView对象target, 如果target非空并且在Map对象targetToAction里已经存在这个action,则取消已经存在的请求,并且将这个action存入map;
    然后提交执行这个Action.

    分发器将这个action进行分发,其实就是通过handler发送一条REQUEST_SUBMIT类型的消息,接着handler收到这条消息后进行处理.

    首先判断Set集合pausedTags里是否包含action的key,这里初次请求是不包含的,略过;
    接着在Map对象里通过action的key获取BitmapHunter,初次请求这里获取的位空.

    首先判断线程池是否关闭,如果关闭了则返回;

    接着通过forRequest方法创建一个BitmapHunter对象;

    最后将这个BitmapHunter(实现了Runnable接口,具体这个runnable干什么我们后面分析)提交到线程池执;
    最后它存入map,下次就可以直接取图片了.


    下面我们详细分析:
    在forRequest方法里通过picasso.getRequestHandlers()获取请求处理器list,这些处理器如下:

    判断请求处理器能否处理本次请求,能处理则构造相应的BitmapHunter.

    具体如何判断,我们看看RequestHandler的canHandleRequest方法,这里以NetworkRequestHandler为例:

    主要是通过scheme进行判断, 所以这里返回的RequestHandler就是NetworkRequestHandler.


    接着我们看看这个BitmapHunter具体干了些什么:

    这里主要是通过hunt方法获取图片,通过获取的结果进行分发,我们继续看看hunt方法干了啥:

    这里是从内存里读取图片的相关操作.

    这里是根据网络策略进行图片读取,这里的OFFLINE是disk only,接着我们看看具体怎么读取?

    这里通过downloader进行加载图片(具体如何加载下面说),然后返回.


    先是根据缓存策略设置缓存控制(http缓存),接着使用OkHttpClient加载图片.

    貌似没有磁盘缓存? 我们看看Downloader的构建过程:

    在构建Downloader的时候,设置了默认的缓存路径,使用http缓存代替disk缓存.(该库和其他下载图片库的主要区别之一:使用4.0+系统上的HTTP缓存来代替Disk磁盘缓存)
    关于http缓存,请参考以下文章:

    HTTP 协议缓存机制详解

    OKHTTP之缓存配置详解





     
    
    
    
    


     





  • 相关阅读:
    Intel Code Challenge Elimination Round (Div.1 + Div.2, combined) C 倒序并查集
    hdu 5573 Binary Tree 构造
    hdu 5514 Frogs 容斥思想+gcd 银牌题
    hdu 5536 Chip Factory 字典树+bitset 铜牌题
    LA 7263 Today Is a Rainy Day bfs+暴力 银牌题
    hdu 5834 Magic boy Bi Luo with his excited tree 树形dp+转移
    hdu 5869 Different GCD Subarray Query BIT+GCD 2016ICPC 大连网络赛
    LA 7043 International Collegiate Routing Contest 路由表 字典树离散化+bitset 银牌题
    校验注解工具类
    java-创建对象实例
  • 原文地址:https://www.cnblogs.com/wytiger/p/6254121.html
Copyright © 2011-2022 走看看