第一次源码分析: 图片加载框架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 ...
随机推荐
- A2W、W2A、A2T、T2A的使用方法
1.A2W和W2A 在<Window核心编程>,多字节和宽字节之间转换比较麻烦的,MultiByteToWideChar函数和WideCharToMultiByte函数有足够多的参数的意义 ...
- SharePoint 2013 开发教程
做了SharePoint有三年了,大家经常会问到,你的SharePoint是怎么学的,想想自己的水平,也不过是初级开发罢了.因为,SharePoint开发需要接触的东西太多了,Windows操作系统. ...
- 国外远控软件DarkComet-RAT
下载地址:[点此下载] 使用步骤: 注册noip.org账号创建主机地址. 安装并配置DUC. 配置监听端口 配置NO-IP Updater 然后点击Update ,配置成功则会提示Success. ...
- 释放Android的函数式能量(I):Kotlin语言的Lambda表达式
原文标题:Unleash functional power on Android (I): Kotlin lambdas 原文链接:http://antonioleiva.com/operator-o ...
- iOS网络1——NSURLConnection使用详解
原文在此 一.整体介绍 NSURLConnection是苹果提供的原生网络访问类,但是苹果很快会将其废弃,且由NSURLSession(iOS7以后)来替代.目前使用最广泛的第三方网络框架AFNetw ...
- Web.xml配置详解之context-param
<context-param> <param-name></param-name> <param-value>></param-value& ...
- [Hadoop in Action] 第4章 编写MapReduce基础程序
基于hadoop的专利数据处理示例 MapReduce程序框架 用于计数统计的MapReduce基础程序 支持用脚本语言编写MapReduce程序的hadoop流式API 用于提升性能的Combine ...
- x01.CodeBuilder: 生成代码框架
根据 Assembly 生成代码框架. 这是学习 AvalonEdit 的一个副产品.学习时,照着源代码新建文件夹,新建文件,添加方法与属性,虽然只是个框架,也要花费大量时间.为什么不让它自动生成呢? ...
- ImportError: No module named 'requests'
补充说明: 当前环境是在windows环境下 python版本是:python 3.4. 刚开始学习python,一边看书一边论坛里阅读感兴趣的代码, http://www.oschina.net/c ...
- Java8 jvm参数
jmap输出 [tomcat@n01 ~]$ /opt/java/jdk1..0_101/bin/jmap -heap Attaching to process ID , please wait... ...