• Fresco 源码分析(二) Fresco客户端与服务端交互(2) Fresco.initializeDrawee()分析 续


    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

  • 相关阅读:
    个人博客作业Week2
    个人作业
    软件工程——个人博客作业三
    软工个人博客二
    软件工程——个人博客作业一
    Linux服务器搭建常用环境(一)
    Swift学习之语言基础
    Python——函数的参数
    Python——函数的调用
    Python 导语
  • 原文地址:https://www.cnblogs.com/pandapan/p/4659960.html
Copyright © 2020-2023  润新知