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. LABJS使用教程

    知道LABJS这个概念其实早于sea.js,但因为sea.js是中文,并且第一眼就喜欢上sea.js的CommonJS所以并没有深入了解过LABJS. 在使用sea.js的时候不可避免的碰到js文件依 ...

  2. Spring学习8-用MyEclipse搭建SSH框架 Struts Spring Hibernate

    1.new一个web project. 2.右键项目,为项目添加Struts支持. 点击Finish.src目录下多了struts.xml配置文件. 3.使用MyEclipse DataBase Ex ...

  3. C# 参考之方法参数关键字:params、ref及out

    如果在为方法声明参数时未使用 ref 或 out,则该参数可以具有关联的值.可以在方法中更改该值,但当控制传递回调用过程时,不会保留更改的值.通过使用方法参数关键字,可以更改这种行为. params ...

  4. The Dirichlet Distribution 狄利克雷分布 (PRML 2.2.1)

    The Dirichlet Distribution 狄利克雷分布 (PRML 2.2.1) Dirichlet分布可以看做是分布之上的分布.如何理解这句话,我们可以先举个例子:假设我们有一个骰子,其 ...

  5. The file couldn’t be opened because you don’t have permission to view it

    because you dont have permission to view it 解决办法 Project---Build Setting中 修改这一项,变成Default Compiler(A ...

  6. powerdesigner设置表主键列为自动增长。

    powerdesigner 版本12.5 创建表就不说了.下面开始介绍设置自动增长列. 1 在表视图的列上创建.双击表视图,打开table properties ———>columens ,双击 ...

  7. HttpRuntime应用程序的运行时

    System.Web.HttpRuntime类是整个Asp.net服务器处理的入口. 这个类提供了一系列的静态属性,反映web应用程序域的设置信息,而且每个web应用程序域中存在一个System.We ...

  8. js控制固定div和随屏滚动div兼容多浏览器和纯css控制(来自网络)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. ubuntu查看版本命令

    有两种方法 1,cat /etc/issue 2,sudo lsb_release -a 这个查询出来的结果比上面的那个全一些.

  10. iOS7: 如何获取不变的UDID

    如何使用KeyChain保存和获取UDID 本文是iOS7系列文章第一篇文章,主要介绍使用KeyChain保存和获取APP数据,解决iOS7上获取不变UDID的问题.并给出一个获取UDID的工具类,使 ...