第一次源码分析: 图片加载框架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 ...
随机推荐
- C#开发微信门户及应用(1)--开始使用微信接口
微信应用如火如荼,很多公司都希望搭上信息快车,这个是一个商机,也是一个技术的方向,因此,有空研究下.学习下微信的相关开发,也就成为日常计划的重要事情之一了.本系列文章希望从一个循序渐进的角度上,全面介 ...
- MYSQL基础知识和操作(二).png
- JavaScript 中的变量命名方法
三种命名方法 在程序语言中,通常使用的变量命名方法有三种:骆驼命名法(CamelCase),帕斯卡命名法(PascalCase)和匈牙利命名法. 依靠单词的大小写拼写复合词的做法,叫做"骆驼 ...
- 在View and Data API中更改指定元素的颜色
大家在使用View and Data API开发过程中,经常会用到的就是改变某些元素的颜色已区别显示.比如根据某些属性做不同颜色的专题显示,或者用不同颜色表示施工进度,或者只是简单的以颜色变化来提醒用 ...
- 信息系统实践手记5-CACHE设计一例
说明:信息系统实践手记系列是系笔者在平时研发中先后遇到的大小的问题,也许朴实和细微,但往往却是经常遇到的问题.笔者对其中比较典型的加以收集,描述,归纳和分享. 摘要:此文描述了笔者接触过的部分信息系统 ...
- 传统IT企业与互联网企业的一点思考
[注意前提]应当说,比较常用的管理策略并没有界线分明的优劣之分,只有适不适合企业的经营战略,团队文化,发展状况等. 之所以有传统IT企业与互联网企业的区别,主要的原因是两者所处的市场环境与经营思路造成 ...
- web工程常用路径的获取方法
此文章是基于 搭建SpringMVC+Spring+Hibernate平台 一. 利用 Spring 取得web工程根路径 1. web.xml 中添加如下: <context-param> ...
- RHEL6.3系统安装
进入安装界面 这里选择跳过 点击下一步 选择安装语言 选择键盘 选择系统储存方式 选择是否格式化储存设备 给安装的系统一个计算机名 选择时区 给ro ...
- .NET中集合已修改;可能无法执行枚举操作 的解决办法
foreach是取只读的,在取的时候数据不能变(包括修改,删除,添加等).要避免这个问题,就应该使用for循环. https://msdn.microsoft.com/zh-cn/library/tt ...
- Centos6.5安装mysql不能启动,应该安装mysql-server
centos中安装mysql很简单如下命令即可 yum install mysql 装好了, 运行mysql ERROR 2002 (HY000): Can't connect to local My ...
