源码分析: 图片加载框架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缓存,请参考以下文章:
源码分析: 图片加载框架Picasso源码分析的更多相关文章
- 第一次源码分析: 图片加载框架Picasso源码分析
使用: Picasso.with(this) .load("http://imgstore.cdn.sogou.com/app/a/100540002/467502.jpg") . ...
- Android 图片加载框架Picasso基本使用和源码完全解析(巨细无比)
写在之前 原本打算是每周更新一篇博文,同时记录一周的生活状态,但是稍微工作忙一点就顾不上写博客了.悲催 还是说下最近的状况,最近两周一直在接公司申请的计费点, 沃商店,银贝壳,微信等等,然后就是不停的 ...
- Android图片加载框架Picasso最全使用教程4
通过前几篇的学习,我们已经对Picasso的加载图片的用法有了很深的了解,接下来我们开始分析Picasso为我们提供的其他高级功能及内存分析,Let’sGo ! Picasso进行图片的旋转(Rota ...
- Android图片加载框架Picasso最全使用教程3
前面我们对Picasso的用法有了一定得了解,下面就分析一下一些特殊情况下,Picasso的用法. 调用.noFade() Picasso的默认图片加载方式有一个淡入的效果,如果调用了noFade() ...
- Android图片加载框架Picasso最全使用教程2
前言 前面我们已经介绍了Picasso的基本用法及如何将一张图片加载到ImageView中,下面我们就利用Picasso在ListView中加载图片;Let’s Go! 一个ListView的简单应用 ...
- Android图片加载框架Picasso最全使用教程1
Picasso介绍 Picasso是Square公司开源的一个Android图形缓存库 A powerful image downloading and caching library for And ...
- 图片加载框架Picasso解析
picasso是Square公司开源的一个Android图形缓存库 主要有以下一些特性: 在adapter中回收和取消当前的下载: 使用最少的内存完成复杂的图形转换操作: 自动的内存和硬盘缓存: 图形 ...
- Android图片加载框架Picasso最全使用教程5
在之前的四篇博客中,我们学习了所有的关于Picasso的主要方法,我们也对这个Picasso有了一个很深的认识,下面就主要对Picasso自身进行分析,这样的话,会让我们更了解Picasso的核心方法 ...
- Android图片加载框架之Picasso
相信做Android开发的对Square公司一定不会陌生,大名鼎鼎的网络请求框架Retrofit就来源于它,今天学习的是该公司出品的图片加载框架Picasso. 项目地址 https://github ...
随机推荐
- 对Android系统权限的认识
Android系统是运行在Linux内核上的,Android与Linux分别有自己的一套严格的安全及权限机制 Android系统权限相关的内容 (一)linux文件系统上的权限 -rwxr-x--x ...
- 用asp.net core 把用户访问记录优化到极致
菜菜呀,前几天做的用户空间,用户反映有时候比较慢呀 CEO,CTO,CFO于一身的CXO 是吗? 菜菜 我把你拉进用户反馈群,你解决一下呀 CEO,CTO,CFO于一身的CXO (完了,以后没清净时候 ...
- VMware(威睿)后端开发笔试题总结
1. Linux中查看系统的发行版本信息 的命令? cat/etc/issue 和 lsb_release 2. linux 挂载一个共享文件夹: mount -t cifc ...
- struts2的基本使用
struts2在web中当作前端控制器,接收来自页面的请求,使用过滤器拦截模式对请求进行拦截并交给相应配置的action类处理. 所以在web中使用最重要的是struts2的核心过滤器StrutsPr ...
- HDU - 1542 扫描线入门+线段树离散化
扫描线算法+线段树维护简介: 像这种求面积的并集的题目,就适合用扫描线算法解决,具体来说就是这样 类似这种给出点的矩形的对角的点的坐标,然后求出所有矩形面积的交集的问题,可以采用扫描线算法解决.图如下 ...
- hibernate在写cfg配置文件自动创建表时报错org.hibernate.MappingException: Could not get constructor for org.hibernate.persister.entity.SingleTableEntityPersister
在用hibernate框架时,写cfg文件,想自动生成表时,一般写<property name="hibernate.hbm2ddl.auto">create</ ...
- sql中return和returns的区别
用户定义函数中,用RETURNS 子句指定该函数返回值的数据类型 return用于返回具体的值/值变量
- elasticsearch elk最全java api 搜索 聚合、嵌套查询
目录 一. 一般查询... 2 (一) matchAllQuery(client). 2 (二) matchQuery(client);3 (三) multiMatchQuery(client);3 ...
- PS滤镜给城市夜空照片添加满天星
原图 一.新建空白图层. 二.填充黑色(编辑→填充). 三.转换为智能对象. 四.添加杂色(滤镜→杂色→添加杂色). 五.使用高斯模糊(滤镜→模糊→高斯模糊). 六.如果你想再次修改模糊效果,可双击该 ...
- PS调出通透唯美阳光外景女生照片
1.稍微增加了一点曝光度,让照片更明亮. 2.对比度的话我现在比习惯加一点,而且 一般导入PS之后我还会按照片情况去加对比度. 3.高光的部分一般会拉回来一点,根据照片调. 4.阴影部分加一点的话会让 ...