4.2.1.2 Fresco.initializeDrawee()的过程 续

继续上篇博客的分析Fresco.initializeDrawee()

    sDraweeControllerBuilderSupplier = new PipelineDraweeControllerBuilderSupplier(context);
SimpleDraweeView.initialize(sDraweeControllerBuilderSupplier);
  1. 初始化了一个sDraweeControllerBuilderSupplier
  2. 将此sDraweeControllerBuilderSupplier用于初始化SimpleDraweeView

还是老的分析思路: 一步一步分析

4.2.1.2.1 sDraweeControllerBuilderSupplier初始化的过程

public PipelineDraweeControllerBuilderSupplier(Context context) {
this(context, ImagePipelineFactory.getInstance());
} public PipelineDraweeControllerBuilderSupplier(
Context context,
ImagePipelineFactory imagePipelineFactory) {
this(context, imagePipelineFactory, null);
} public PipelineDraweeControllerBuilderSupplier(
Context context,
ImagePipelineFactory imagePipelineFactory,
Set<ControllerListener> boundControllerListeners) {
mContext = context;
mImagePipeline = imagePipelineFactory.getImagePipeline();
mPipelineDraweeControllerFactory = new PipelineDraweeControllerFactory(
context.getResources(),
DeferredReleaser.getInstance(),
imagePipelineFactory.getAnimatedDrawableFactory(),
UiThreadImmediateExecutorService.getInstance());
mBoundControllerListeners = boundControllerListeners;
}

构造方法,相互调用,总结过程

  1. 获取到了ImagePipelineFactory的实例,经过查看源码,只是将Fresco第一步初始化中的ImagePipelineFactory,获取到了这个实例,这里采用了单例的形式

  2. 获取到ImagePipleline,并且保存在这个Supplier中,这个里面代码看似只有这么几行,但是包涵的内容很多,还是先从广度看,然后再从深度看(这个方面作为遗留的Q2,一会儿再看)

    *** ImagePipelineFactory.getImagePipeline()源码 ***

    public ImagePipeline getImagePipeline() {

    if (mImagePipeline == null) {

    mImagePipeline =

    new ImagePipeline(

    getProducerSequenceFactory(),

    mConfig.getRequestListeners(),

    mConfig.getIsPrefetchEnabledSupplier(),

    getBitmapMemoryCache(),

    getEncodedMemoryCache(),

    mConfig.getCacheKeyFactory());

    }

    return mImagePipeline;

    }

在获取ImagePipeline()中,如果为空,创建了一个

3. 创建了一个PipelineDraweeControllerFactory,并且保存到这个Supplier中

看到这里,我们先继续的广度分析,就是继续的分析SimpleDraweeView.initialize(sDraweeControllerBuilderSupplier)的过程

4.2.1.2.2 SimpleDraweeView.initialize(sDraweeControllerBuilderSupplier)的过程

在上面的分析,我们已经看到sDraweeControllerBuilderSupplier使用的是PipelineDraweeControllerBuilderSupplier

接下来,我们就看SimpleDraweeView.initialize(sDraweeControllerBuilderSupplier)的过程

从下面的代码,我们看到sDraweeControllerBuilderSupplier保存在了SimpleDraweeView中,SimpleDraweeView能够很简单的使用,是因为Fresco帮助我们在这里初始化了很多东西

  private static Supplier<? extends SimpleDraweeControllerBuilder> sDraweeControllerBuilderSupplier;

  /** Initializes {@link SimpleDraweeView} with supplier of Drawee controller builders. */
public static void initialize(
Supplier<? extends SimpleDraweeControllerBuilder> draweeControllerBuilderSupplier) {
sDraweeControllerBuilderSupplier = draweeControllerBuilderSupplier;
}

接着,以SimpleDraweeView的xml解析的方式来分析初始化的过程,我们发现,这里调用了我们的sDraweeControllerBuilderSupplier的get方法

*** SimpleDraweeView 的xml构造方式源码分析 ***

  public SimpleDraweeView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
} private void init() {
if (isInEditMode()) {
return;
}
Preconditions.checkNotNull(
sDraweeControllerBuilderSupplier,
"SimpleDraweeView was not initialized!");
mSimpleDraweeControllerBuilder = sDraweeControllerBuilderSupplier.get();
}

先别着急,我们再接着看,在使用xml解析的方式,我们还用到了一个setImageUri方法,再接着看这个方法,在setImageUri中,创建了一个DraweeController,然后设置给了自身,在构造DraweeController的时候,我们发现,调用了mSimpleDraweeControllerBuilder的build()方法

*** setImageURI(Uri)的源码分析 ***

  /**
* Displays an image given by the uri.
*
* @param uri uri of the image
* @undeprecate
*/
@Override
public void setImageURI(Uri uri) {
setImageURI(uri, null);
} /**
* Displays an image given by the uri.
*
* @param uri uri of the image
* @param callerContext caller context
*/
public void setImageURI(Uri uri, @Nullable Object callerContext) {
DraweeController controller = mSimpleDraweeControllerBuilder
.setCallerContext(callerContext)
.setUri(uri)
.setOldController(getController())
.build();
setController(controller);
}

到这里,我们先总结一下:

  1. SimpleDraweeView中的sDraweeControllerBuilderSupplier是PipelineDraweeControllerBuilderSupplier
  2. SimpleDraweeView中的controller是什么呢?那么这里就需要看看sDraweeControllerBuilderSupplier的get到什么ControllerBuilder?
  3. 对应的ControllerBuilder,build出什么controller
  4. controller又是怎么样将提交请求的
  5. 遗留的Q2问题什么时候可以分析

看到这几个问题,我们发现,我们的分析,任重而道远

4.2.1.2.3 PipelineDraweeControllerBuilderSupplier的get()分析

这里只是创建了一个PipelineDraweeControllerBuilder,并且这个builder保存了imagePipeline和mPipelineDraweeControllerFactory

*** PipelineDraweeControllerBuilder.get()分析 ***

@Override

public PipelineDraweeControllerBuilder get() {

return new PipelineDraweeControllerBuilder(

mContext,

mPipelineDraweeControllerFactory,

mImagePipeline,

mBoundControllerListeners);

}

*** PipelineDraweeControllerBuilder的构造方法 ***

在这里,我们看不到什么,那么就继续看build()方法吧

public PipelineDraweeControllerBuilder(

Context context,

PipelineDraweeControllerFactory pipelineDraweeControllerFactory,

ImagePipeline imagePipeline,

Set boundControllerListeners) {

super(context, boundControllerListeners);

mImagePipeline = imagePipeline;

mPipelineDraweeControllerFactory = pipelineDraweeControllerFactory;

}

查看build方法时,便已经看到了这个PipelineDraweeControllerBuilder的继承结构

AbstractDraweeControllerBuilder

--| VolleyDraweeControllerBuilder

--| PipelineDraweeControllerBuilder

Volley相关的我们就不看了,这个是和Vollery框架结合使用的,有兴趣可以自己研究下,大同小异

这次直接从方法调用来看即可,这次我们就要看到请求到底是如何产生的了

*** AbstractDraweeControllerBuilder.build()方法源码分析 ***

非核心代码,这次就忽略了,我们主要目的是要看到如何发送请求的,到后面请求如何反馈到前台,我们再详细分析其他代码

在build中,最关键的是buildController(),而在buildController中,最核心的是obtainController(),然后其他的是设置请求的一些信息,比如说设置请求的ImageRequest,其他的是设置重试等等

  /** Builds the specified controller. */
@Override
public AbstractDraweeController build() {
validate(); // if only a low-res request is specified, treat it as a final request.
if (mImageRequest == null && mMultiImageRequests == null && mLowResImageRequest != null) {
mImageRequest = mLowResImageRequest;
mLowResImageRequest = null;
} return buildController();
} /** Builds a regular controller. */
protected AbstractDraweeController buildController() {
AbstractDraweeController controller = obtainController();
maybeBuildAndSetRetryManager(controller);
maybeAttachListeners(controller);
return controller;
} /** Concrete builder classes should override this method to return a new controller. */
protected abstract AbstractDraweeController obtainController();

而在这里,发现obtainController()是抽象方法,那么就是找子类呗

*** PipelineDraweeControllerBuilder.obtainController()源码分析 ***

在获取controller的方法中,我们还是以第一次初始化为例,那么就是else的部分,这里就是用mPipelineDraweeControllerFactory创建了一个newController

@Override

protected PipelineDraweeController obtainController() {

DraweeController oldController = getOldController();

PipelineDraweeController controller;

if (oldController instanceof PipelineDraweeController) {

controller = (PipelineDraweeController) oldController;

controller.initialize(

obtainDataSourceSupplier(),

generateUniqueControllerId(),

getCallerContext());

} else {

controller = mPipelineDraweeControllerFactory.newController(

obtainDataSourceSupplier(),

generateUniqueControllerId(),

getCallerContext());

}

return controller;

}

这块要关键的分析了,因为已经到了重点了

  controller = mPipelineDraweeControllerFactory.newController(
obtainDataSourceSupplier(),
generateUniqueControllerId(),
getCallerContext());

我们一步一步看

  1. obtainDataSourceSupplier()获取到了一个DataSourceSupplier
  2. 然后mPipelineDraweeControllerFactory类new了一个controller

这也没看出来什么,是吧,我们下节就得来点插叙,结合DraweeController和这里的获取Supplier直接的关系,那么基本的请求流程,我们算基本分析结束

安卓源码分析群: Android源码分析QQ1群号:164812238

Fresco 源码分析(二) Fresco客户端与服务端交互(2) Fresco.initializeDrawee()分析 续的更多相关文章

  1. java客户端与服务端交互通用处理 框架解析

    一.综述 java 客户端与服务端交互过程中,采用NIO通讯是异步的,客户端基本采用同一处理范式,来进行同异步的调用处理. 处理模型有以下几个要素: 1. NIO发送消息后返回的Future 2. 每 ...

  2. c++ 网络编程(一)TCP/UDP windows/linux 下入门级socket通信 客户端与服务端交互代码

    原文作者:aircraft 原文地址:https://www.cnblogs.com/DOMLX/p/9601511.html c++ 网络编程(一)TCP/UDP  入门级客户端与服务端交互代码 网 ...

  3. Android客户端与服务端交互之登陆示例

    Android客户端与服务端交互之登陆示例 今天了解了一下android客户端与服务端是怎样交互的,发现其实跟web有点类似吧,然后网上找了大神的登陆示例,是基于IntentService的 1.后台 ...

  4. Fresco 源码分析(二) Fresco客户端与服务端交互(1) 解决遗留的Q1问题

    4.2 Fresco客户端与服务端的交互(一) 解决Q1问题 从这篇博客开始,我们开始讨论客户端与服务端是如何交互的,这个交互的入口,我们从Q1问题入手(博客按照这样的问题入手,是因为当时我也是从这里 ...

  5. Fresco 源码分析(二) Fresco客户端与服务端交互(3) 前后台打通

    4.2.1.2.4 PipelineDraweeControllerBuilder.obtainController()源码分析 续 上节中我们提到两个核心的步骤 obtainDataSourceSu ...

  6. TCP学习之二:客户端与服务端的连接

    主要参考张子阳大神的博客:http://www.cnblogs.com/JimmyZhang/category/101698.html TcpClient是对Socket的封装 一个TcpClient ...

  7. spring-oauth-server实践:使用授权方式四:client_credentials 模式的客户端和服务端交互

    spring-oauth-server入门(1-11)使用授权方式四:client_credentials 模式的客戶端 一.客户端逻辑 1.界面入口(credentials_access_token ...

  8. android 38 Abdroid客户端和服务端交互

    服务端: package com.sxt.day05; import java.io.IOException; import java.util.ArrayList; import javax.ser ...

  9. UDP网络程序,客户端和服务端交互原理

    创建一个udp客户端程序的流程是简单,具体步骤如下: 创建客户端套接字 发送/接收数据 关闭套接字 UDP是面向无连接的通讯协议,UDP数据包括目的端口号和源端口号信息,由于通讯不需要连接,所以可以实 ...

随机推荐

  1. 如何使用MASM来编译、连接、调试汇编语言

    先声明下,本人绝非大虾,也只是菜鸟一个,写此文的目的只是为了加深我对知识的理解罢了.好,进入正题.我是把masm解压后发在D盘中的一个叫masm的文件里,在masm文件里新建个记事本(记事本功能是很强 ...

  2. 弱键(Weak Key, ACM/ICPC Seoul 2004, UVa1618)

    I think: 给出k(4≤k≤5000)个互不相同的整数组成的序列Ni,判断是否存在4个整数Np.Nq.Nr和Ns(1≤p<q<r<s≤k),使得Nq>Ns>Np&g ...

  3. Web Service 元数据注释(JSR 181)

    Web Service 元数据注释(JSR 181) @WebService 1.serviceName: 对外发布的服务名,指定 Web Service 的服务名称:wsdl:service.缺省值 ...

  4. IIS负载均衡-Application Request Route详解第二篇:创建与配置Server Farm(转载)

    IIS负载均衡-Application Request Route详解第二篇:创建与配置Server Farm 自从本系列发布之后,收到了很多的朋友的回复!非常感谢,同时很多朋友问到了一些问题,有些问 ...

  5. Leetcode 之Construct Binary Tree(52)

    根据先序和中序构造二叉树.根据中序和后序构造二叉树,基础题,采用递归的方式解决,两题的方法类似.需要注意的是迭代器的用法. //先序和中序 TreeNode *buildTree(vector< ...

  6. poj1094 拓扑 Sorting It All Out

    Sorting It All Out Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 29744   Accepted: 10 ...

  7. 最长公共子串 NYOJ 36

    http://acm.nyist.net/JudgeOnline/problem.php?pid=36 最长公共子序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 ...

  8. 如何使用setup.py文件

    setup.py文件的使用:% python setup.py build #编译% python setup.py install    #安装% python setup.py sdist     ...

  9. 【leetcode】Best Time to Buy and Sell Stock II

    Best Time to Buy and Sell Stock II Say you have an array for which the ith element is the price of a ...

  10. 22.整数二进制表示中1的个数[Get1BitCount]

    [题目] 输入一个整数,求该整数的二进制表达中有多少个1.例如输入10,由于其二进制表示为1010,有两个1,因此输出2. [分析] 如果一个整数不为0,那么这个整数至少有一位是1.如果我们把这个整数 ...